上一章主要讲了转换到数字,字符串和布尔类型的一些知识点,那么这一讲接着上面的继续讲。javascript
思考下面这个问题:java
console.log(+"123"); // 123 console.log(-"123"); // -123 console.log(+"abc"); // NaN console.log(-"abc"); // NaN
+这个很容易理解,就是把字符串转成了数字,而-这个呢,除了把字符串转为数字之外,还会吧这个数字加否。因此不管+仍是-都会进行类型转换,惟一的区别,就是-会置否而+不会。数组
那么+除了看成一元运算符外,还有一个更广为人知的就是做为加法运算符。函数
那么加法运算符的话,其实是有两种可能性的,一种是字符串的拼接,另外一种就是作运算。接下来我们就对这方面详细的讲解一下。工具
先说结论,若是在+的其中有一个操做数是字符串或者能够转为字符串的话,那么就进行字符串拼接。code
反之,若是俩都是数字的话,则进行加法运算。对象
这时候,确定会有人问,假如说我有其余的数据类型呢,又不是数字又不是字符串,好比说数组啊,对象啊,布尔值啥的,ip
那么若是是引用数据类型,则先转为基本数据类型,再进行比较。文档
若是是布尔呢,若是加法的另外一边是数字的话,那么他就会转为数字,若是是字符串的话,就直接拼接啦.字符串
上面说了一大堆的理论的东西,想必你们看着也累了。来上例子。
console.log(true + 11); // 12 console.log(true + false); // 1 console.log(true + '11'); // "true11"
这个很明显能够看出,若是操做数是数字的话,或者说,操做数都是字符串的话,那么布尔值会先转为数字,再进行拼接操做,若是有一个操做数是字符串的话,那就不转啦,直接拼接。
那么若是是对象类型,它是先转为基本数据类型,怎么转呢,其实就是先调用valueOf,若是valueOf不存在,或者返回的不是基本数据类型,就调用toString,若是toString也没有或者是返回的不是基本数据类型呢,那估计就直接报错了,看例子。
var obj = { valueOf() { return [2, 3]; }, toString() { return "sss"; } } var obj1 = { valueOf() { return 111; }, toString() { return "abc"; } } var obj2 = { valueOf() { return []; }, toString() { return { abc: 'liuhaitao', } } } console.log(obj + 1); // "sss1" console.log(obj1 + 1); // 112 console.log(obj2 + 1); // "Cannot convert object to primitive value"
那么下面一个例子就很容易理解了。
console.log([1].valueOf()); // [1] console.log([1] + [2]); // 12
由于数组的valueOf的值依然为数组,因此他们转的时候,就会调用toString,因此就转成了字符串啦,俩字符串进行拼接,获得最终结果
减法运算符(-)
很显然,减法运算符就是作减法的,他很单纯,就只是作减法,可是呢,这个有一个知识点,就是,减法里的操做数,若是不是数字的话,那么会先转为数字类型的。
console.log("123" - 0); // 123 console.log([3] - [1]); // 2 console.log({valueOf() { return 3}} - {valueOf() { return 2}}); // 1
这个很明显,第一个和第二个的结果都是转为了数字再进行运算的,那第三个呢,其实这个就是对象的转化方式,若是有valueOf的话,会先执行valueOf找出基本类型值,没有或者不是基本类型值就找toString,最后呢,吧基本类型值转为数字再进行减法运算 。
好了,加法和减法都说完了,那么乘法和除法呢,其实和减法相似,都是转为数字这样的。
console.log("123" * 0); // 0 console.log([3] * [1]); // 3 console.log({valueOf() { return 3}} * {valueOf() { return 2}}); // 6
想看乘法和除法其余的细节和本文关系不是太大,因此就不细讲了,详情请查阅文档ecma文档:
https://www.ecma-internationa...
https://www.ecma-internationa...
还有本节最后一部分,就是有关于逻辑与(&&)和逻辑或(||)
为啥要特意介绍他俩呢,由于他俩的语法和其余语言的语法特性彷佛有那么一些区别。来看代码
var a = 42; var b = "abc"; var c = null; console.log(a || b); // 42 console.log(a && b); // "abc" console.log(c || b); // "abc" console.log(c && b); // null
这一块能够看出,他和其余语言的不一样之处在于,他的运算的结果,并非true和false,而是具体的值,也就是说
||符号的时候,若是第一个操做数是true,则返回第一个操做数,若是是false返回第二个,
&&相反,若是第一个操做数是true,则返回第二个操做数,若是是false则返回第一个。
那这个有啥用呢?
其实能够利用这个的特性简化咱们的代码,好比说
function exec () { console.log('exec'); } true && exec(); // exec var a = undefined; var b = a || 10; console.log(b); // 10
这个表明了应用的两个方面,&&能够作函数执行的前置判断,后面那个呢,能够作缺省时的默认值,你能够仔细观察一下,在一些压缩代码工具,压缩完后的代码,不少都把if 条件判断改为了&&,此次知道缘由了吧。
参考书籍《你不知道的Javascript中卷》