自增和自减
++
和--
,这两个操作符直接借鉴自C,分别有两种形式,前置和后置,在此不再赘述两者之间的区别,有兴趣的可以参见++i和i++的区别.与C等强类型语言不同的是它们不仅适用于整数,还可以用于字符串、布尔值、浮点数值和对象,其中隐藏着类型转换.在应用于不同的值时,递增和递减操作符遵循下列规则。
- 字符串.在应用于一个包含有效数字字符的字符串时,先将其转换为数字值,再执行加减 1 的操作;否则其值变为
NaN
. - 布尔值.false转化为0,true转化为1,再执行加减操作.
- 浮点数.直接进行加减操作.
- 对象.先调用对象的
valueOf()
方法取得一个可供操作的值a,然后对该值进行上述的规则.如果a的结果是NaN
,则调用toString()
方法后再应用上述规则. - 运算的结果都是转化为数字变量
下面的代码展示了这个例子:
var s1 = '23',
s2 = 'abc',
b = false,
f = 1.234,
o = {
valueOf: function() {
return '123';
}
};
s1++;
s2++;
b++;
f++;
o++;
console.log(s1, s2, b, f, o); // 24 NaN 1 2.234 124
值得我们注意的是NaN
也是数值变量,你可以执行typeof NaN
得到的结果将是'number'
.
一元加和减运算符
加运算符
数值型的前面放上+
号不会产生任何影响,非数值类型就会进行类型转换.具体转化规则如下:
- Boolean:false -> 0,true -> 1
- String:按照一定的规则进行解析
- Object:先调用
valueOf()
和(或)toString()
方法,再得到转化的值.
减运算符
该运算符主要用于表示负数,应用与非数值的时候先遵循和一元加运算符相同的规则,然后将得到的值变为负数.
var o = {
valueOf: function() {
return '123';
}
};
console.log(-o); // -123
布尔操作符
逻辑非
逻辑非!
操作符可以应用与任何类型,并且返回结果都将是布尔类型,它的工作原理是先转化成布尔,再进行取反.让我们回顾一下js中的true和false.
javascript中的
false
只有:false
,空字符串(''
或者""
),null
,undefined
,NaN
.注意:空对象(a = {}
)和空数组([]
)以及无穷大(Infinity
)都是true
.
基于这个原理,同时使用两个逻辑非运算符可以模拟Boolean()
函数的行为,严格转化为boolean
类型.
console.log(!!0); // false
console.log(!!''); // false
console.log(!!undefined); // false
console.log(!!NaN); // false
console.log(!!123); // true
逻辑与和逻辑或
逻辑与(&&
),逻辑或(||
)也可以用于任意的js类型,其返回值也可以是任意的js类型.我们要注意:这两个操作符都是短路操作.
true && 1; // 1
undefined && false; // undefined
true && NaN; // NaN
我们可以使用短路或模拟ES6中的默认参数:
function say(content) {
var DEFAULT_CONTENT = 'HELLO WORLD';
var con = content || DEFAULT_CONTENT;
console.log(con);
}
say(); // HELLO WORLD
say('YES'); // YES
加性运算符
加操作符
- 其中一个操作数是
NaN
,结果是NaN
Infinity
+Infinity
=Infinity
-Infinity
+(-Infinity)
=-Infinity
-Infinity
+Infinity
=NaN
- 如果其中一个操作数是字符串,则进行字符串的转化,再进行拼接.
- 如果一个操作数是对象,则调用
toString()
方法获得字符串的值,再进行字符串的拼接操作 - 如果是
null
和undefined
则调用String()
函数取得字符串表现形式'null'
和'undefined'
减操作符
- 如果有一个操作数是 NaN ,则结果是 NaN
Infinity - Infinity = NaN
-Infinity - (-Infinity) = NaN
Infinity - (-Infinity) = Infinity
-Infinity - Infinity = -Infinity
- 如果有一个操作数是字符串、布尔值、 null 或 undefined ,则先在后台调用
Number()
函数将其转换为数值,然后再根据前面的规则执行减法计算。如果转换的结果是NaN
,则减法的结果就是NaN
console.log(6 - false); // 6
console.log(NaN - 1); // NaN
console.log(17 - "12"); // 5
console.log(12 - "a23"); // NaN
关系运算符
关系运算符作用于非数值的时候也要进行类型转化:
- 如果两个操作数都是字符串,则比较两个字符串对应的字符编码值。
- 如果一个操作数是数值,则将另一个操作数转换为一个数值,然后执行数值比较。
- 如果一个操作数是对象,则调用这个对象的
valueOf()
方法,用得到的结果按照前面的规则执行比较。如果对象没有valueOf()
方法,则调用toString()
方法,并用得到的结果根据前面的规则执行比较。 - 如果一个操作数是布尔值,则先将其转换为数值,然后再执行比较。
- 任何操作数和
NaN
进行关系运算的结果都是false
.
"23" < 12; // false,转化成数字
'a' > 5; // false,a 转成了NaN
1 > NaN; // false
1 <= NaN; // false
Tips
Q1:如何快速在js中进行进制转化?
A1:调用num.toString(radix)
即可,其中num表示需要转化进制的数,radix表示进制,例如:
var num = 17;
num.toString(2); // 10001
num.toString(8); // 21
num.toString(10); // 17
num.toString(16); // 11