Javascript笔记--数据类型
1.Undefined
2.Null
3.Boolean
4.String
5.Number
6.Symbol(ES6新增加)
7.Object
Undefined & Null
问题1:为什么有的编程规范要求用void 0代替undefined?
Undefined表示变量声明但是未定义,任何变量未赋值都是undefined类型,值为undefined。
一般我们可以用全局变量undefined来表达这个值,或者void运算来把表达式变成undefined。
但是,JS的代码undefined是一个变量,而非关键字,设计失误之一,所以我们为了避免无意中的篡改,使用void 0来获取undefined值
Null类型也只有一个值,null,表示空值,JS关键字之一,可以放心使用。
Boolean
Boolean类型两个值,true和false,同样有关键字来表示这两个值。
String
问题2:字符串有最大长度吗?
String表示文本数据。最大长度为2^53-1,但是有趣的是,此最大长度并非字符数。
String的意义并非“字符串”,而是UTF16编码,我们字符串的操作charAt、charCodeAt、length等针对的都是UTF16编码。
所以,字符串的最大长度实际上是受字符串的编码长度影响的。
note:现行的字符集国际标准,字符是以Unicode的方式表示的,每一个Unicode的码点表示一个字符,理论上范围无限。
UTF是Unicode的编码方式,规定了码点在计算机中的表示方式,常见的有UTF16和UTF8。
Unicode的码点通常用U+???来表示,其中???表示16进制的码点值。
0-65536(U+0000 - U+FFFF)的码点被称为基本字符区域(BMP)。
JS字符串把每个UTF16单元当做一个字符来处理,所以处理非BMP的字符时,应该格外小心。这个设计继承自JAVA。
Number
表示我们通常意义上的“数字”,通常对于的一般是有理数。
2^64 - 2^53 + 3个值
基本符合IEEE 745-2008规定的双精度浮点数规则,但是JavaScript为了表示几个额外的语言场景,规定了几个例外的情况:
(无穷大概念是为了防止除以0出错而引入的)
·NaN,占用9007199254740990,原本是符合IEEE的数字;
·Infinity,无穷大;
·-Infinity,负无穷大;
JS中有+0和-0,在加法类运算中没有区别,但是除法场合,忘记监测“除以-0,会得到-Infinity的情况”经常会导致错误。
区分两者的方式就是监测1/x,是Infinity还是-Infinity。
问题三:为什么JS中,0.1+0.2不能=0.3?
console.log(0.1+0.2 == 0.3)返回false。
number类型运算底层先将其转换为二进制,将二进制运算,运算结果再转换为十进制。
因为number是64位双精度,小数部分52位,0.1转二进制数是无限循环的,所以四舍五入了,故发生了精度的丢失,而0.1+0.2又需要保留有效的数字,所以又发生了精度丢失。
正确的比较方法是使用JS的最小精度值:
console.log(Math.abs(0.1 + 0.2 -0.3) <= Number.EPSILON);
Symbol
Symbol 是 ES6 中引入的新类型,它是一切非字符串的对象 key 的集合,在 ES6 规范中,整个对象系统被用 Symbol 重塑。
Symbol 可以具有字符串类型的描述,但是即使描述相同,Symbol 也不相等。我们创建 Symbol 的方式是使用全局的 Symbol 函数。例如:
var mySymbol = Symbol("my symbol");
一些标准中提到的 Symbol,可以在全局的 Symbol 函数的属性中找到。例如,我们可以使用 Symbol.iterator 来自定义 for…of 在对象上的行为:
var o = new Object
o[Symbol.iterator] = function() {
var v = 0
return {
next: function() {
return { value: v++, done: v > 10 }
}
}
};
for(var v of o)
console.log(v); // 0 1 2 3 ... 9
这些标准中被称为“众所周知”的 Symbol,也构成了语言的一类接口形式。它们允许编写与语言结合更紧密的 API。
Object
Object 是 JavaScript 中最复杂的类型,也是 JavaScript 的核心机制之一。
Object 表示对象的意思,它是一切有形和无形物体的总称。
问题四:为什么给对象添加的方法能用在基本类型上?
在 JavaScript 中,对象的定义是“属性的集合”。
属性分为数据属性和访问器属性,二者都是 key-value 结构,key 可以是字符串或者 Symbol 类型。
这里重点从类型的角度来介绍对象类型。
提到对象,我们必须要提到一个概念:类。因为 C++ 和 Java 的成功,在这两门语言中,每个类都是一个类型,二者几乎等同,以至于很 多人常常会把 JavaScript 的“类”与类型混淆。
事实上,JavaScript 中的“类”仅仅是运行时对象的一个私有属性,而 JavaScript 中是无法自定义类型的。
JavaScript 中的几个基本类型,都在对象类型中有一个“亲戚”。它们是:Number;String;Boolean;Symbol。
所以,我们必须认识到 3 与 new Number(3) 是完全不同的值,它们一个是 Number 类型, 一个是对象类型。
Number、String 和 Boolean,三个构造器是两用的,当跟 new 搭配时,它们产生对象,当直接调用时,它们表示强制类型转换。
Symbol 函数比较特殊,直接用 new 调用它会抛出错误,但它仍然是 Symbol 对象的构造器。JavaScript 语言设计上试图模糊对象和基本类型之间的关系,我们日常代码可以把对象的方法在基本类型上使用,比如:
console.log("abc".charAt(0)); //a
甚至我们在原型上添加方法,都可以应用于基本类型,比如以下代码,在 Symbol 原型上添加了 hello 方法,在任何 Symbol 类型变量都可以调用。
Symbol.prototype.hello = () => console.log("hello");
var a = Symbol("a");
console.log(typeof a); //symbol,a并非对象
a.hello(); //hello,有效
所以答案就是. 运算符提供了装箱操作,它会根据基础类型构造一个临时对象,使得我们能在基础类型上调用对应对象的方法。

浙公网安备 33010602011771号