运算

70 阅读3分钟

参考阮一峰教程的,供自己查看的

对象的相加

运算中有对象,会将对象转成原始类型的值,然后相加

例子1

	var obj = {a:1}
    	console.log(obj.valueOf()); //{a:1}
        console.log(obj.valueOf().toString());//[object Object]
        console.log(obj+1);  //[object Object]1

例子2

	var obj1 = {
            a:6,
            valueOf:function(){
                return 1
            },
            toString:function(){
                console.log('aaa');//这里不会执行
                return 2
            }
        }
        console.log(obj1+1); //2

例子3

	var obj2 = {
            a:6,
            toString:function(){
                console.log('aaa');//这里可以执行
                return 2
            }
        }
        console.log(obj2+1);//3

由此可见对象转成原始值会先调用valueOf(没有自定义valueOf会返回对象自身)方法,如果返回的是原始值则返回,不是原始值再调用toString方法

特例: 如果是一个Date对象实例,则调用toString方法,好像不调用valueOf方法

例子1

	var ob3 = new Date()
        ob3.toString = function (){
            return '3'
        }
        ob3.valueOf = function (){
            console.log('valueOf');//这里不会执行
            return '2'
        }
        console.log(ob3+1);//'31'

例子2

	var ob3 = new Date()
        ob3.valueOf = function (){
            console.log('valueOf');//这里不会执行
            return '2'
        }
        console.log(ob3+1);//Sat Mar 06 2021 16:56:32 GMT+0800 (中国标准时间)1
//Number和+一元运算符 作用相同
Number([]) //0
Number({}) //NaN
Number('') //0
Number(null) //0
Number(undefined) //NaN
Number('false') //NaN
Number(false)  //0

非相等运算符比较

如果两个运算的值都是原始值,如果两个都是字符串,就比较unicode,否则,则转成数值在比较

'a'>'b'  //false
5 > '4' // true
// 等同于 5 > Number('4')
// 即 5 > 4
true > false // true
// 等同于 Number(true) > Number(false)
// 即 1 > 0
2 > true // true
// 等同于 2 > Number(true)
// 即 2 > 1

如果运算元素是对象,则会先转为原始类型的值,再比较 对象转原始值要先调用valueOf->再调用toString

var x = [2];
x > '11' // true
// 等同于 [2].valueOf().toString() > '11'
// 即 '2' > '11'
x.valueOf = function () { return '1' };
x > '11' // false
// 等同于 [2].valueOf() > '11'
// 即 '1' > '11'
[2] > [1] // true
// 等同于 [2].valueOf().toString() > [1].valueOf().toString()
// 即 '2' > '1'
[2] > [11] // true
// 等同于 [2].valueOf().toString() > [11].valueOf().toString()
// 即 '2' > '11'
{ x: 2 } >= { x: 1 } // true
// 等同于 { x: 2 }.valueOf().toString() >= { x: 1 }.valueOf().toString()
// 即 '[object Object]' >= '[object Object]'

相等运算符比较

原始类型的值会转换成数值再进行比较

1 == true // true
// 等同于 1 === Number(true)
0 == false // true
// 等同于 0 === Number(false)
2 == true // false
// 等同于 2 === Number(true)
2 == false // false
// 等同于 2 === Number(false)
'true' == true // false
// 等同于 Number('true') === Number(true)
// 等同于 NaN === 1
'' == 0 // true
// 等同于 Number('') === 0
// 等同于 0 === 0
'' == false  // true
// 等同于 Number('') === Number(false)
// 等同于 0 === 0
'1' == true  // true
// 等同于 Number('1') === Number(true)
// 等同于 1 === 1
'\n  123  \t' == 123 // true
// 因为字符串转为数字时,省略前置和后置的空格

对象与原始值的比较

// 数组与数值的比较
[1] == 1 // true
// 等同于 [1].valueOf().toString() == 1
// 等同于'1' == 1

// 数组与字符串的比较
[1, 2] == '1,2' // true
// 等同于 [1,2].valueOf().toString() == '1,2'
// 等同于'1,2' == '1,2'

// 对象与布尔值的比较
[1] == true // true
// 等同于 [1].valueOf().toString() == true
// 等同于'1' == true
// 等同于 Number('1') === Number(true)
// 等同于 1 === 1
[2] == true // false
// 等同于 [2].valueOf().toString() == true
// 等同于'2' == true
// 等同于 Number('2') === Number(true)
// 等同于 2 === 1

undefined == undefined // true
null == null // true
undefined == null // true
undefined===null //false
undefined === undefined // true
null === null // true