犀牛书第四章主要讲解了关于 JavaScript 中的 表达式 和 运算符。数组
本篇主要说如下 运算符 和 运算符相关的类型转换 部分。函数
数据类型和类型之间的转换规则请查看:post
eval('some code');
var geval = eval;
geval('some code');
'use strict';
eval('some code');
复制代码
关系运算符 老是会返回一个布尔值。学习
== 运算符在进行判断时会对操做数进行隐式类型转换,按照如下步骤进行判断ui
1 == 2 // false
null == undefined // true
123 == '123' // true
true == '1' // true
({
valueOf: () => {
console.log('valueOf');
return {};
},
toString: () => {
console.log('toString');
return '123';
}
}) == 123; // valueOf toString true
({
valueOf: () => {
console.log('valueOf');
return 123;
},
toString: () => {
console.log('toString');
return '123';
}
}) == '123'; // valueOf true
NaN == NaN; // false
复制代码
比较运算符(>, <, >=, <=)在进行运算时会按照如下规则进行判断:编码
<= 实际为 不大于(a >= b ==> !(a < b),排除 NaN)、>= 实际为 不小于(a <= b ==> !(a > b),排除 NaN),不依赖与相等运算符的比较规则。spa
+ 运算符 依赖于操做数,若是一个操做数为字符串或者转换为原始值后为字符串,会将另外一个操做数做为字符串进行拼接。不然将进行数值加法计算。code
++ -- 运算符依赖于操做数的位置,运算符在操做数前时为 前增量,返回计算后的值,运算符在操做数后是为 后增量,返回计算前的值。cdn
++ -- 运算符的操做数 只会被转换为数字。对象
位运算符会 将操做数转换为数字,NaN、Infinity、-Infinity 会被转换为 0。
位运算符针对 32 位整形,会 忽略小数点和超出 32 位的二进制位。
直接 eval 会在调用它的上下文做用域下执行,会 影响到调用的做用域。
间接 eval 会在 全局上下文进行执行,不会影响调用的做用域。
严格模式下 eval 能够读写局部变量,可是不能新增局部变量、函数。
&& 和 || 可用来进行 代码短路。
?: 可 实现相似 if 的做用。
true && console.log(123); // 123
false && console.log(123); //
true || console.log(123); //
false || console.log(123); // 123
true ? console.log(123) : console.log(456); // 123
false ? console.log(123) : console.log(456); // 456
复制代码
这里套用一下 MDN 上的运算符优先级表格
运算符的 优先级决定了在复杂表达式运算过程当中,运算的前后顺序。
从上往下优先级越低,最高的是括号,而后是属性访问、对象建立等,最后是赋值运算符、yield、逗号运算符。
a = 1 * 2 - 1
// 按照运算符的优先级,会先计算 1 * 2 得出 2,而后计算 2 - 1 得出 1,而后将 1 赋值给 a
复制代码
表格的第三行定义了列出了各运算符的结合性,能够看看 MDN 上关于结合性的定义,结合性决定了相同的运算符之间的计算顺序。
Associativity determines the way in which operators of the same precedence are parsed.
1 / 2 / 3
// 按照 / 的结合性从左往右,等价于
(1 / 2) / 3
a = b = c
// 按照 = 的结合性从右往左,等价于
a = (b = c)
复制代码
每一个运算符所须要的的操做数个数不一样,+ 运算符须要 1 个或 2 个操做数,?: 须要三个操做数,根据操做数的数量,能够将运算符分类成 一元运算符、二元运算符、三元运算符。
一个 复杂表达式的运算顺序和运算符的优先级、结合性相关。 而子表达式在计算中老是按照从左往右的顺序计算表达式的。 具体看最下方。
运算符对操做数进行计算时会 将操做数转换为想要的类型(隐式类型转换)。
左值 指表达式 只能出如今赋值运算符的左侧,包括变量、对象属性、数组元素。
关于左值概念说起的较少,具体解释一下,左值和右值的区别,当一个变量、对象属性、数组元素出如今赋值运算符的左边时,取的是他的左值,能够认为取出的是他的内存地址,而出如今右边是取的是他的右值也就是他的实际值,可使用 getter 试试,左值出如今左边时,getter 不会被触发,由于左值不关心他的实际值,只关心他的地址。
var a = {
get b() {
console.log('get');
return 123;
}
};
// get 被打印,取出右值
var c = a.b;
// get 未被打印,取出左值
a.b = 1;
复制代码
除了赋值运算符,还有 delete 运算符的操做数也是左值。
部分运算符带有 反作用,如 delete、赋值运算符、++、--。