若是你能確切的答出能夠,那恭喜你,你能夠繞道了
有人會說,這個問題好奇葩,放在別的語言裏,這要是能輸出true,估計是見鬼了,可是你別說,放在js中好真有可能。最近在一我的的推特上提了一個問題:git
在這篇文章中,我將解釋這段代碼的原理:github
const a = { num: 0, valueOf: function() { return this.num += 1 } }; const equality = (a==1 && a==2 && a==3); console.log(equality); // true
你能夠打開chorme瀏覽器,而後打開開發者模式,在console中輸入這段代碼,你就能夠看到輸出結果([windows]: Ctrl + Shift + J [mac]: Cmd + Opt + J)windows
其實也沒有,能有的就是js中的兩個概念:瀏覽器
注意:這題裏面咱們用的是==而不是===,在js中==表明的是等於而不是全等,那麼就存在變量的隱式轉化問題。這就意味着結果會比咱們所指望的更多的可能性。對於js的隱式轉化,真的有不少文章,我推薦一下如下幾篇博客,若是你想要了解,能夠點進去:函數
推薦博客測試
JavaScript提供了一種將對象轉化爲原始值的方法:Object.prototype.valueOf(),默認狀況下,返回正在被調用的對象。this
咱們舉個例子:lua
const a = { num: 0 }
咱們能夠對上述對象使用valueOf方法,他會返回一個對象。spa
a.valueOf(); // {num: 0}
是否是很酷,咱們能夠用typeOf來檢測一下這個輸出結果的類型:prototype
typeof a.valueOf(); // "object"
爲了讓valueOf能夠更方便將一個對象轉化成原始值,咱們能夠重寫他,換種說法就是咱們能夠經過valueOf來返回一個字符串、數字、布爾值等來代替一個對象,咱們能夠看如下代碼:
a.valueOf = function() { return this.num; }
咱們已經重寫了原生的valueOf()方法,當咱們調用valueOf的時候,他會返回a.num。那咱們如今運行如下:
a.valueOf(); // 0
咱們獲得0了,這很合理,由於0就是賦給a.num的值。那咱們能夠來作幾個測試:
typeof a.valueOf(); // "number" a.num == a.valueOf() // true
很好,但爲何這個很重要呢?
這很重要,由於當你兩種不一樣類型的遇到相等操做符的時候,js會對其進行類型轉化——它企圖將操做數的類型轉化爲相似的。
在咱們的問題中:(a==1 && a==2 && a==3)
JavaScript會企圖將對象轉化成數字的類型,進行比較。當要轉化的是一個Object的時候,JavaScript會調用valueOf()方法。
自從咱們改變了valueOf()方法以後,咱們能不能作到如下幾點呢:
a == 0 // true
咱們作到了,異常輕鬆。
如今咱們須要作的的一點是:當咱們每次去調用a的值的時候,能改變它。
幸運的是,在JavaScript中有+=
符號。
+=
這個運算符能夠輕鬆的去改變一個的值,咱們能夠舉個簡單的例子:
let b = 1 console.log(b+=1); // 2 console.log(b+=1); // 3 console.log(b+=1); // 4
正如你所見的,咱們每次使用加法賦值運算符,可讓咱們的變量增長。
因此咱們能夠將這個觀念用到valueOf()中。
a.valueOf = function() { return this.num += 1; }
當咱們每次調用valueOf的時候,他會將變量增長1返回給咱們。
隨着這個改變,咱們來運行下面的代碼:
const equality = (a==1 && a==2 && a==3); console.log(equality); // true
這就是它的工做原理。
記住下面兩點:
因此比較的時候咱們每次都能獲得true。
a == 1 -> a.valueOf() == 1 -> a.num += 1 == 1 -> 0 += 1 == 1 -> 1 == 1 -> true a == 2 -> a.valueOf() == 2 -> a.num += 1 == 2 -> 1 += 1 == 2 -> 2 == 2 -> true a == 3 -> a.valueOf() == 3 -> a.num += 1 == 3 -> 2 += 1 == 3 -> 3 == 3 -> true
謝謝你觀看這個小實驗,但願你能從中學到東西,有興趣的朋友也能夠去個人github點個star,你的支持是我持續輸出的動力,謝謝!!!