每日一題1214之資料型別轉換題
阿新 • • 發佈:2020-12-16
技術標籤:每日一題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() 方法會直接在一個物件上定義一個新屬性,或者修改一個物件的現有屬性,並返回此物件。資料劫持是對這個屬性的翻譯。
我個人的理解就是:使用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屬性值新增一個函式,每次進行比較都會呼叫這個函式。