数据类型隐式转换默认调用toString()/ Object.defineProperty方法完成

436 阅读2分钟

var a = ?;
if (a == 1 && a == 2 && a == 3) {
    console.log(1);
}

分析:让a等于啥的情况下,可以使a即等于1也等于2也等于3 

let obj = {    n: 0};console.log(obj.toString()); //=>"[object Object]"  它是obj实例基于__proto__找到Object.prototype上的toString方法,然后去执行的 
let obj = {    n: 0,    toString: function () {        return 'OK';    }};console.log(obj.toString()); //=>"OK" 此处执行的是自己的私有方法(私有中有,就不会再向原型上进行查找了)

解决方案一:

首先区分==和===的区别?

1. ==进行比较的时候,两边数据类型不一致,则先转换为相同的数据类型,然后再进行比较

2. 除了 对象==字符串 是把对象转换为字符串,其余的都是转换为数字(其中比较特殊的是对象,对象转换为数字,首先要把他转换为字符串 => toString 方法)

第一种方法
var a = {
    n:0;
    toString:function(){
           // a.toString() : this=>a     return ++this.n;     };
};
if (a == 1 && a == 2 && a == 3) {    console.log('OK');}第二种方法:
  让每一次toString的时候都执行shift,删除数组中的第一项,每一次删除返回的结果就是删除的这一项var a = [1, 2, 3];a.toString = a.shift;if (a == 1 && a == 2 && a == 3) {    console.log('OK');}

解决方案二:

 Object.defineProperty:监听某个对象的某个属性,可以在获取或者设置属性的值的时候,做一些自己要做的事情(Vue框架MVVM实现的原理就是基于这个完成的) =>同样原理的还可以使用Proxy代理处理

这里要注意的是:   全局上下文中变量不带VAR相当于给全局window设置一个属性

var i = 0;Object.defineProperty(window, 'a', {    get() {        // 只要获取a的值,就一定会触发get方法执行        return ++i;    }});if (a === 1 && a === 2 && a === 3) {    console.log('OK');}