Symbol(符号)是 ECMAScript 6 新增的数据类型。符号是原始值,且符号实例是唯一、不可变的。 符号的用途是确保对象属性使用唯一标识符,不会发生属性冲突的危险。
尽管听起来跟私有属性有点类似,但符号并不是为了提供私有属性的行为才增加的(尤其是因为 Object API 提供了方法,可以更方便地发现符号属性)。相反,符号就是用来创建唯一记号,进而用作非字符串形式的对象属性。
// 创建全局符号
let s = Symbol.for('foo');
console.log(Symbol.keyFor(s)); // foo
// 创建普通符号
let s2 = Symbol('bar');
console.log(Symbol.keyFor(s2)); // undefined
如果传给 Symbol.keyFor()的不是符号,则该方法抛出 TypeError:
Symbol.keyFor(123); // TypeError: 123 is not a symbol
一元操作符
1. 递增/递减操作符
包括 a++ ,a-- ,++a, --a ,四个操作符。
后缀版与前缀版的主要区别在于,后缀版递增和递减在语句被求值后才发生。
这
4
个操作符可以作用于任何值,意思是不限于整数
——
字符串、布尔值、浮点值,甚至对象都可
以。递增和递减操作符遵循如下规则。
- 对于字符串,如果是有效的数值形式,则转换为数值再应用改变。变量类型从字符串变成数值。
- 对于字符串,如果不是有效的数值形式,则将变量的值设置为 NaN 。变量类型从字符串变成数值。
- 对于布尔值,如果是 false,则转换为 0 再应用改变。变量类型从布尔值变成数值。
- 对于布尔值,如果是 true,则转换为 1 再应用改变。变量类型从布尔值变成数值。
- 对于浮点值,加 1 或减 1。
- 如果是对象,则调用其(第 5 章会详细介绍的)valueOf()方法取得可以操作的值。对得到的值应用上述规则。如果是 NaN,则调用 toString()并再次应用其他规则。变量类型从对象变成数值
let s1 = "2";
let s2 = "z";
let b = false;
let f = 1.1;
let o = {
valueOf() {
return -1;
}
};
s1++; // 值变成数值 3
s2++; // 值变成 NaN
b++; // 值变成数值 1
f--; // 值变成 0.10000000000000009(因为浮点数不精确)
o--; // 值变成-2
2. 一元加和减
一元加和减操作符
对大多数开发者来说并不陌生,它们在
ECMAScript
中跟在高中数学中的用途一 样。一元加由一个加号(+
)表示,放在变量前头,对数值没有任何影响:
let num = 25;
num = +num;
console.log(num); // 25
如果将一元
加
应用到非数值,则会执行与使用
Number()
转型函数一样的类型转换:布尔值
false 和 true
转换为
0
和
1
,字符串根据特殊规则进行解析,对象会调用它们的
valueOf()
和
/
或
toString() 方法以得到可以转换的值。下面的例子演示了一元加在应用到不同数据类型时的行为:
let s1 = "01";
let s2 = "1.1";
let s3 = "z";
let b = false;
let f = 1.1;
let o = {
valueOf() {
return -1;
}
};
s1 = +s1; // 值变成数值 1
s2 = +s2; // 值变成数值 1.1
s3 = +s3; // 值变成 NaN
b = +b; // 值变成数值 0
f = +f; // 不变,还是 1.1
o = +o; // 值变成数值-1
对数值使用一元减会将其变成相应的负值(如上面的例子所示)。在应用到非数值时,一元减会遵循与一元加同样的规则,先对它们进行转换,然后再取负值:
let s1 = "01";
let s2 = "1.1";
let s3 = "z";
let b = false;
let f = 1.1;
let o = {
valueOf() {
return -1;
}
};
s1 = -s1; // 值变成数值-1
s2 = -s2; // 值变成数值-1.1
s3 = -s3; // 值变成 NaN
b = -b; // 值变成数值 0
f = -f; // 变成-1.1
o = -o; // 值变成数值 1
一元加和减操作符主要用于基本的算术,但也可以像上面的例子那样,用于数据类型转换。主要用于基本运算,但也可以用来数据类型的转换。
1. 按位非
按位非操作符用波浪符(
~
)表示,它的作用是返回数值的一补数。按位非是
ECMAScript
中为数 不多的几个二进制数学操作符之一。
let num1 = 25; // 二进制 00000000000000000000000000011001
let num2 = ~num1; // 二进制 11111111111111111111111111100110
console.log(num2); // -26
这里,按位非操作符作用到了数值
25
,得到的结果是
26
。由此可以看出,按位非的最终效果是对 数值取反并减 1
,就像执行如下操作的结果一样:
let num1 = 25;
let num2 = -num1 - 1;
console.log(num2); // "-26"
实际上,尽管两者返回的结果一样,但
位操作的速度快得多
。这是因为位操作是在数值的底层表示 上完成的。
~符号的表示意思就是 ~x = -x - 1;