每日一题12/14之数据类型转换题

a等于什么会让下面条件成立?

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

首先&&是与逻辑运算符,意思是如果每一项都为真,则整个运算结果为真,题目就变成了a等于什么的时候,a == 1 和 a == 2和 a == 3同时为真。

思路1:利用 == 的隐式转换

每次 == 都是一次隐式转换,== 在比较的时候,如果两边类型不一致,则转换为相同的数据类型。
假设a是一个对象,那么对象转化为数字类型,应该怎么转换呢?

对象转换为数字或者字符串:

  • 1.查找对象的 Symbol.toPrimitive
  • 2.调用对象.valueOf(),找到它 的原始值(也就是原始数据类型),js中的原始值如下:number\string\boolean\null\undefined\symbol\bigint
  • 3.对象.toString() 变为字符串
  • 4.字符串转换数字 Number(str)

从这个角度出发,可以通过改写a的Symbol.toPrimitive 或者valueOf()来使a的值能在==比较的时候变化。

 var a = {
    i: 0
};
// 或者改写valueOf / toString
a[Symbol.toPrimitive] = function () {
    // this->a
    return ++this.i;
};
if (a == 1 && a == 2 && a == 3) {
    console.log('OK');
}
//或者写成这个样子,因为有人觉得跑题,他觉得多出来了a[Symbol.toPrimitive] = function () {}这一块。
 var a = {
    i: 0,
    [Symbol.toPrimitive]() {
        return ++this.i;
    }
};
if (a == 1 && a == 2 && a == 3) {
    console.log('OK');
}

**思路2:ES6 数据劫持 **

什么是数据劫持,数据劫持有什么用呢?
Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。数据劫持是对这个属性的翻译。

关于数据劫持的具体细节来自MDN

我个人的理解就是:使用Object.defineProperty() 来给对象修改or添加属性。

let obj = {};
Object.defineProperty(obj, 'name', {
    // 以后当我们操作对象的name属性的时候(获取或者设置),触发getter/setter
    get() {
        return 'hhhh';
    },
   //如果是obj.name,就会返回hhhh',如果是设置name属性值,那么设置的属性值就是对象的新属性值。
    set(value) {
        console.log(value);
    }
});

在这里插入图片描述
那么对于这道题来说,数据劫持有什么用呢?

var a = 12; //全局上下文中,基于var/function声明变量,也相当于给window设置了属性 window.a=12
var i = 0;
Object.defineProperty(window, 'a', {
    get() {
        return ++i;
    }
});
if (a == 1 && a == 2 && a == 3) {
    console.log('OK');
}

给window的a属性值添加一个函数,每次进行比较都会调用这个函数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值