新增数据类型
1 Symbol
1.1 什么是Symbol
ES5 的对象属性名都是字符串,这容易造成属性名的冲突。比如,你使用了一个他人提供的对象,但又想为这个对象添加新的方法,新方法的名字就有可能与现有方法产生冲突。如果有一种机制,保证每个属性的名字都是独一无二的就好了,这样就从根本上防止属性名的冲突。这就是 ES6 引入Symbol
的原因。
ES6 引入了一种新的原始数据类型Symbol
,表示独一无二的值。它是 JavaScript 语言的第七种数据类型
1.2 Symbol的使用
-
Symbol 值通过
Symbol
函数生成。 -
这就是说,对象的属性名现在可以有两种类型,一种是原来就有的字符串,另一种就是新增的 Symbol 类型。凡是属性名属于 Symbol 类型,就都是独一无二的,可以保证不会与其他属性名产生冲突
let s = Symbol();
typeof s
// "symbol"
let s1 = Symbol('foo');
let s2 = Symbol('bar');
s1 // Symbol(foo)
s2 // Symbol(bar)
s1.toString() // "Symbol(foo)"
s2.toString() // "Symbol(bar)"
1.3 Symbol表示独一无二的值
//1.之前出现的问题
/* let obj = {
name: "lily",
todo() {
console.log("eat");
}
}
//修改
obj.name = "xiaowang";
obj.todo = () => {
console.log("someThing~")
}
console.log(obj.name);
obj.todo(); */
//需求:让新增的属性和方法不和之前的冲突
let name = Symbol("name");
let todo = Symbol("todo");
let obj = {
name: "小王"
}
obj[name] = "老王"
console.log(obj);
console.log(obj.name)
console.log(obj[name])
1.4 Symbol的注意事项
-
Symbol中传入的字符串没有任何意义,只是用来描述Symbol的
{ let obj1 = { name: "lily",//原有对象拥有name属性 age: 18, } let name = Symbol("name"); let age = Symbol("age"); obj1[name] = "xiaowang"; obj1[age] = 21; console.log(obj1) }
-
Symbol不能使用New调用
new Symbol();//Symbol is not a constructor
-
类型转换的时候,不能转数字
console.log(String(Symbol("a")));//Symbol(a) console.log(Boolean(Symbol()));//true // console.log(Symbol() + 1);//Cannot convert a Symbol value to a number // console.log(Number(Symbol()));//Cannot convert a Symbol value to a number
-
如果把Symbol当作一个对象的属性和方法的时候,一定要用一个变量来储存,否则定义的属性和方法没有办法使用
{ let obj = { name: "lily",//原有对象拥有name属性 age: 18, } obj[Symbol()] = "再见";//如果直接设置,则再也获取不到这个属性了 console.log(obj); console.log(obj[Symbol()])//undefined }
-
for in 不能遍历出来,可以使用Object.getOwnPropertySymbols方法来拿
{ let obj = { name: "lily",//原有对象拥有name属性 age: 18, } let name = Symbol(); obj[name] = "再见";//如果直接设置,则再也获取不到这个属性了 for (let i in obj) { console.log(i); } //可以使用 Object.getOwnPropertySymbols方法来拿 console.log(Object.getOwnPropertySymbols(obj));//[Symbol()] }
2 BigInt
-
JavaScript 所有数字都保存成 64 位浮点数,这给数值的表示带来了两大限制。一是数值的精度只能到 53 个二进制位(相当于 16 个十进制位),大于这个范围的整数,JavaScript 是无法精确表示的,这使得 JavaScript 不适合进行科学和金融方面的精确计算。二是大于或等于2的1024次方的数值,JavaScript 无法表示,会返回
Infinity
。 -
引入了一种新的数据类型 BigInt(大整数),来解决这个问题。BigInt 只用来表示整数,没有位数的限制,任何位数的整数都可以精确表示。
// 超过 53 个二进制位的数值,无法保持精度 Math.pow(2, 53) === Math.pow(2, 53) + 1 // true // 超过 2 的 1024 次方的数值,无法表示 Math.pow(2, 1024) // Infinity const a = 2172141653n; const b = 15346349309n; // BigInt 可以保持精度 a * b // 33334444555566667777n // 普通整数无法保持精度 Number(a) * Number(b) // 33334444555566670000
-
为了与 Number 类型区别,BigInt 类型的数据必须添加后缀
n
。1234 // 普通整数 1234n // BigInt // BigInt 的运算 1n + 2n // 3n
-
BigInt 与普通整数是两种值,它们之间并不全等。
42n === 42 // false
-
typeof
运算符对于 BigInt 类型的数据返回bigint
。