1. 程式人生 > 其它 >每日一題1214之資料型別轉換題

每日一題1214之資料型別轉換題

技術標籤:每日一題jsjavascript

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屬性值新增一個函式,每次進行比較都會呼叫這個函式。