最近整理了一下,就决定跟大家讨论一下最近对于Javascripet的型别认识。
弱型别 VS 强型别
Javascripet是一种「弱型别」的语言,所以会产生很多你意想不到噁心的事情
至于什么是弱型别?
小弟弟我来为大家解释一下,在程式语言的世界里有分两种型别系统
1.强型别 (程式所定义的变数型别=变数在执行的型别)
这类型的程式语言在宣告变数的时候就已经把资料型别指定好给变数,如果对这个变数去做错误的型别运算他就会直接喷错误给你看。 (废话!你还想拿明朝的剑斩清朝的官啊)
举个例子来说,以下是一段ruby的程式码
a=2b='3'puts a+b #会喷错
因为ruby是一种强型别的语言,上面的程式码一定会给你这段
String can't be coerced into Integer (TypeError)
大概的意思就是说不能将一个字符串强制转换为整数
2.弱型别 (语法简洁,但是要注意型态转换会产生非预期的错误)
以下是一段Javascripet的程式码
const a = 2;const b = '3';console.log(a+b); //会印出5
Javascripet会判断你使用到+号是要做运算,并透过自动转型的特性去把字串型别转换成数字。
所以这下你就可以拿明朝的剑斩清朝的官(喂~
接下来就是重头戏啦,在javascript的世界中只有分基本型别(Primitives)跟物件型别(Object)两大类。如果想要确认型别可以透过typeof()来确认。
基本型别
有六种资料型别是基本型别:Boolean、Null、Undefined、Number、BigInt、String、Symbol(于EC6加入)。
字串(string)
字串其实就是字元的集合,字元代表一个字母的意思。字串就是一个单词的概念。举个例子:A是字元Apple是字串,
但在Javascript的世界里没有字元的概念,只有字串。字串会用' '(单引号)或是" "(双引号)包住,切记不可以混用单引号开头就是单引号结尾。以下用程式码示範:
const str = 'hello world';const str2 = "这是一个字串";
单引号内如果有用到单引号或双引号内有用到双引号会出错
const str = 'I'm 18 year-old' //会出错!
但如果改成这样
const str = "I'm 18 year-old"; //这个没问题
如果有非用不可的状况就可以用跳脱字元(escape character)来处理
const str = 'I\'m 18 year-old'; //没问题
如果想要连接字串可以使用加号
const str = 'hi!' + 'I am Eazy';
这边补充一下ES6后加入的新语法`` 反引号(backtick)
这个超好用的东西,可以让你在字串中直接塞变数不用在透过加号也可以让你直接支援多行字串。这边就不啰唆直上程式码
const age = 18;const str = ` hello word ! I am ${age} year-old `; console.log(str); //可以印出 hello word ! I am 18 year-old
数字(Number)
Javascript只有一种数值的型别,那就是Number。不管是整数(integer)或是带有小数点的浮点数字都是属于这一类:
const a = 10;const b = 12.2;
除了整数与小数外,额外还有几种特殊的数字:Infinity(无限大)
、-Infinity(负无限大)
,以及NaN(Not a Number)
。
如果用一个正数除以0会得到Infinity(无限大)
,用负数除以0会得到-Infinity(负无限大)
,那如果用0/0会得到NaN。Infinity/Infinit或Infinity(负无限大)/-Infinity(负无限大)都是NaN。
最好玩的是NaN并不等于NaN。这是什么平行时空的概念,长得一样的人有不一样的人生喔
而且如果你拿NaN去跟任何数字做运算也只会得到NaN,所以它就是一个数字型别来代表不是数字。
Javascript里还有一个特别的状况那就是小数点运算,它是基于二进位浮点数算术标準(IEEE 754)这边细说太複杂,有兴趣的人可以看看维基百科我把连结放下方
提供个例子:
0.1+0.2 === 0.3 //false
布林值(boolean)
相对其他基本型别,布林值就很简单只有两种,不是true就是false。通常会用在判断式if...else用来作流程控制。这根本超级直男,不是一就是二啊
空值(null)
在多数程式语言都有一个这样的设计来代表空值,在Ruby的世界里是用nil。null型别就只有一个值就是null。
如果要比较饶舌的解释,Null就是「这个变数(可能曾经有值,也可能没有)但是现在起他就是没有值。」如果要使用null可以直接宣告,以下:
const a = null;Number(null); //用强制转型会跑出0
如果用typeof()去检查Null会发现他会跳出Object
啊不是跟我说他是基本型别,你有没有搞错啊!
其实他是一个美丽的错误bug,因为在Javascript的初期实作中,Javascript的值是用「型别」的标籤与实际内容的值来组成。由于Object
这个型别的标籤是0,所以跟null的标籤(惯例会以0x00表示)搞混后导致有这样的错误结果。
undefined(未定义)
在Javascript中如果宣告一个变数没有赋予值就会得到这个结果,所以他跟null有点不太一样。null是有赋予值不过是空值,undefined是尚未赋予值,所以还不知道是什么。
const a ;console.log(a); //会跑出undefinedNumber(undefined); // NaN
但还有一个会出现的东西叫not defined
,在你还没宣告变数就使用它会出现
console.log(b); //not defined
可以预设JS会给变数预设的值,就是undefined。这后面可以再出一篇文章细谈JS宣告变数后有分建立期
与执行期
。
BigInt(超大整数)
Javascript用来表示值太大而无法用Number表示的数值。JavaScript是双精度浮点会留一个位置给科学记好左边的1,所以Number最大安全表示是2的53次方-1=9,007,199,254,740,991。
const previouslyMaxSafeInteger = 9007199254740991n;const alsoHuge = BigInt(9007199254740991); // 9007199254740991nconst hugeString = BigInt("9007199254740991"); // 9007199254740991n
所以超过这9,007,199,254,740,991,会加上bigint但是只能表示整数。
symbol(象徵)
Javascript称为Symbol值或只是一个Symbol,每一个Symbol的值都是独一无二的。是ES6后新出的语法。
物件型别(Object)
在Javascript中,除了基本型别外都可以归类在物件型别。那什么是物件呢?以下就来整理一下物件型别有哪些。
物件
一个物件可以是个零或是多种属性的集合。基本属性上是一组Key跟value的组合而成,一个属性的值可以是某个基本型别,也可以是物件或是一个函数。如果要宣告一个物件可以直接用{}
来宣告。
const cat = { name: '小橘', age: 6, action: function(){ console.log('吃饭'); }};
如果要将物件的属性存取可以透.
或是[ ]
来存取,以下用上面的物件示範
const cat = { name: '小橘', age: 6, action: function(){ console.log('吃饭'); }};cat.name // '小橘‘cat["age"] // 6
物件并没有先后顺序,所以如果你想要获取value,可以直接透过key来取得。
阵列(Array)
阵列也是一种物件型别,同样是多个元素的集合体。所以一样可以放基本型别、阵列、物件、函式。但是阵列与物件的差别在于阵列是有顺序的集合体。透过[ ]
加上索引值(index),索引值(index)是由0开始。宣告一个阵列很简单以下:
const a = [1, 2, 3];console.log(a[0]); //可以拿到1
阵列也有很多方法可以使用,之后也可以整理出来在细谈这边就不在多赘述。
函式(function)
函式在javascript中也是物件型别,函式的概念有点像是我们在国中在使用的f(x)=2x+1(有参数跟引数)。
在javascript中宣告函式的方法有很多种,但不管是哪种方法,通常函式都会拥有三个部分:
function addNumber(number1, number2){ return number1 + number2;}addNumber(1, 2); //3addNumber(2, 4); //6addNumber(4, 5); //9
切记要在透过return回传结果,不然会返还undefined
不然会像以下这个例子这样
function echoNumber(x){ console.log(x);}echoNumber(1); //会跑出两个结果 一个是1 一个是undefined
为什么要写function
?假设当有一段程式码你会一直重複使用到你就可以考虑写成一个function
。
以上是大概整理出来的Javascript的型别,当然不是像小弟弟我写的那么简单而已。
只能说Javascript的世界真是博大精深,还有很多细节与设计奇妙的地方地雷之后可以在补充。
如果大家对于学Javascript有兴趣,我自己本身很推荐一本书,很多观念我也是重新看过在釐清。
我把连结放底下,我怕等等被说业配
参考文献
0 陷阱!0 误解!8 天重新认识 JavaScript!(iT邦帮忙铁人赛系列书 - 02)
IEEE 754维基百科
Day04 undefined与not defined
初学者跪着学JavaScript Day8 : 资料型别:BigInt
MDN