对于object和number、string、boolean之间的转换关系,ToPrimitive是指转换为js内部的原始值,如果是非原始值则转为原始值,调用valueOf()和toString()来实现。
前言
-
[ ] Object 与Primitive,需要Object转为Primitive
-
[ ] String 与 Boolean,需要两个操作数同时转为Number。
-
[ ] String/Boolean 与 Number,需要String/Boolean转为Number。
-
[ ] undefined 与 null ,和所有其他值比较的结果都是false,他们之间==成立
-
[ ] 如果参数是Date对象的实例,那么先toString()如果是原始值则返回,否则再valueOf(),如果是原始值则返回,否则报错。
-
[ ] 如果参数不是Date对象的实例,同理,不过先valueOf再toString()。
1.一些例子
![] //false;
+[] // 0
+![] // 0
[]+[] // ""
{}+{}//"[object Object][object Object]"
{}+[]//0
{a:0}+1 // 1
[]+{}//"[object Object]"
[]+![]//"false"
{}+[]//0
![]+[] // "false"
''+{} //"[object Object]"
{}+'' //0
[]["map"]+[] //"function map() { }"
[]["a"]+[] // "undefined"
[][[]] + []// "undefined"
+!![]+[] //"1"
+!![] //1
1-{} //NaN
1-[] //1
true-1 //0
{}-1 //-1
[]==![] //true
2.从[]==![]开始
3.更多玩法
[]['push'](1) //[1]
[]["map"] //function map() { [native code] }
[]["map"]+[] // "function map() { [native code] }"
(![]+[])[+[]] //"f"
(![]+[])[+!![]] // "a"
([][[]] + [])[(+!![] + [] + [] + +![] ) >> +!![]] +
$$('*')[~~[]].nodeName[- ~ -+~[]] +
(this + [])[+!![]+[] + +[] - !!{} - !!{}] +
([]+![])[+!!{} << +!![] -~[]] +
({}+{})[+!![] -~[]]
4. 两个面试题
var a = {
num: 0,
valueOf: function() {
return this.num += 1
}
};
var eq = (a==1 && a==2 && a==3);
console.log(eq);
//或者改写他的tostring方法
var num = 0;
Function.prototype.toString = function(){
return ++num;
}
function a(){}
//还可以改写ES6的symbol类型的toP的方法
var a = {[Symbol.toPrimitive]: (function (i) { return function(){return ++i } }) (0)};
var a = {
num: 4,
valueOf: function() {
return this.num -= 1
}
};
var res = (a==3 && a==2 && a==1);
console.log(res);
var b = 1
Object.defineProperty(window, 'a', {
get:function() { return b++; }
})
var s = (a===1 && a===2 && a === 3 )
console.log(s)
class Cash {}
const a = new Cash(1)
const b = new Cash(100)
console.log(`${a.add(b)},${Cash.add(a,b)},${new Cash(a+b)}`) // 101,101,101
class Cash {
constructor (a) {
this.m = a // 缓存真正的值
this.valueOf = function () {
console.log('value')
return a
}
}
add ($) { // a.add(b)
return this.m + $
}
toString () { // 隐式转换调用
return this.m
}
static add (v1, v2) { //Cash.add
return v1 + v2
}
}
最后