JavaScript中如何讓?x?==?1?&&?x?==?2?&&?x?==?3?等式成立
前言
某次面試,面試官突然問(wèn)道:“如何讓 x 等于 1 且讓 x 等于 2 且讓 x 等于 3 的等式成立?”
話音剛落,筆者立馬失去意識(shí),雙眼一黑,兩腿一蹬,心里暗罵:什么玩意兒!
雖然當(dāng)時(shí)沒(méi)回答上來(lái),但覺(jué)得這題非常有意思,便在這為大家分享下后續(xù)的解題思路:
寬松相等 == 和嚴(yán)格相等 === 都能用來(lái)判斷兩個(gè)值是否“相等”,首先,我們要明確上文提到的等于指的是哪一種,我們先看下二者的區(qū)別:
(1) 對(duì)于基礎(chǔ)類型之間的比較,== 和 === 是有區(qū)別的:
- (1.1) 不同類型間比較,== 比較“轉(zhuǎn)化成同一類型后的值”看“值”是否相等,=== 如果類型不同,其結(jié)果就是不等
- (1.2) 同類型比較,直接進(jìn)行“值”比較,兩者結(jié)果一樣
(2) 對(duì)于引用類型之間的比較,== 和 === 是沒(méi)有區(qū)別的,都進(jìn)行“指針地址”比較
(3) 基礎(chǔ)類型與引用類型之間的比較,== 和 === 是有區(qū)別的:
- (3.1) 對(duì)于 ==,將引用類型轉(zhuǎn)化為基礎(chǔ)類型,進(jìn)行“值”比較
- (3.2) 因?yàn)轭愋筒煌?== 結(jié)果為 false
“== 允許在相等比較中進(jìn)行強(qiáng)制類型轉(zhuǎn)換,而 === 不允許。”
由此可見(jiàn),上文提到的等于指的寬松相等 ==,題目變?yōu)?“x == 1 && x == 2 && x == 3”。
那多種數(shù)據(jù)類型之間的相等比較又有哪些呢?筆者查閱了相關(guān)資料,如下所示:
同類型數(shù)據(jù)之間的相等比較
- 如果
Type(x)
等于Type(y)
ES5 規(guī)范 11.9.3.1 這樣定義: - 如果
Type(x)
是Undefined
,返回true
。 - 如果
Type(x)
是Null
,返回true
。- 如果
Type(x)
是Number
,則 - 如果
x
是NaN
,返回false
。 - 如果
y
是NaN
,返回false
。 - 如果
x
與y
的數(shù)字值相同,返回true
。 - 如果
x
為+0
,y
為-0
,返回true
。 - 如果
x
為-0
,y
為+0
,返回true
。
- 如果
- 如果
Type(x)
是String
,則如果x
和y
是字符的序列完全相同(相同的長(zhǎng)度和相同位置相同的字符),則返回true
。否則,返回false
。 - 如果
Type(x)
是Boolean
,則如果x
和y
都為true
或都為false
,則返回true
。否則,返回false
。 - 如果
x
和y
指向同一對(duì)象,則返回true
。否則,返回false
。
null 和 undefined 之間的相等比較
null
和 undefined
之間的 == 也涉及隱式強(qiáng)制類型轉(zhuǎn)換。ES5 規(guī)范 11.9.3.2-3 這樣定義:
- 如果
x
為null
,y
為undefined
,則結(jié)果為true
。 - 如果
x
為undefined
,y
為null
,則結(jié)果為true
。
在 == 中,null
和 undefined
相等(它們也與其自身相等),除此之外其他值都不和它們兩個(gè)相等。
這也就是說(shuō), 在 == 中null
和 undefined
是一回事。
var a = null; var b; a == b; // true a == null; // true b == null; // true a == false; // false b == false; // false a == ""; // false b == ""; // false a == 0; // false b == 0; // false
字符串和數(shù)字之間的相等比較
ES5 規(guī)范 11.9.3.4-5 這樣定義:
- 如果
Type(x)
是數(shù)字,Type(y)
是字符串,則返回x
==ToNumber(y)
的結(jié)果。 - 如果
Type(x)
是字符串,Type(y)
是數(shù)字,則返回ToNumber(x)
==y
的結(jié)果。
var a = 42; var b = "42"; a === b; // false a == b; // true 復(fù)制代碼
因?yàn)闆](méi)有強(qiáng)制類型轉(zhuǎn)換,所以 a
=== b
為 false
,42 和 "42" 不相等。
根據(jù)規(guī)范,"42" 應(yīng)該被強(qiáng)制類型轉(zhuǎn)換為數(shù)字以便進(jìn)行相等比較。
其他類型和布爾類型之間的相等比較
ES5 規(guī)范 11.9.3.6-7 這樣定義:
- 如果
Type(x)
是布爾類型,則返回ToNumber(x)
==y
的結(jié)果; - 如果
Type(y)
是布爾類型,則返回x
==ToNumber(y)
的結(jié)果。
仔細(xì)分析例子,首先:
var x = true; var y = "42"; x == y; // false
Type(x)
是布爾值,所以 ToNumber(x)
將 true
強(qiáng)制類型轉(zhuǎn)換為 1,變成 1 == "42",二者的類型仍然不同,"42" 根據(jù)規(guī)則被強(qiáng)制類型轉(zhuǎn)換為 42,最后變成 1 == 42,結(jié)果為 false
。
對(duì)象和非對(duì)象之間的相等比較
關(guān)于對(duì)象(對(duì)象 / 函數(shù) / 數(shù)組)和標(biāo)量基本類型(字符串 / 數(shù)字 / 布爾值)之間的相等比較,ES5 規(guī)范 11.9.3.8-9 做如下規(guī)定:
- 如果
Type(x)
是字符串或數(shù)字,Type(y)
是對(duì)象,則返回x
==ToPrimitive(y)
的結(jié)果; - 如果
Type(x)
是對(duì)象,Type(y)
是字符串或數(shù)字,則返回ToPromitive(x)
==y
的結(jié)果。
什么是 toPrimitive() 函數(shù)?
**應(yīng)用場(chǎng)景:**在 JavaScript
中,如果想要將對(duì)象轉(zhuǎn)換成基本類型時(shí),再?gòu)幕绢愋娃D(zhuǎn)換為對(duì)應(yīng)的 String
或者 Number
,實(shí)質(zhì)就是調(diào)用 valueOf
和 toString
方法,也就是所謂的拆箱轉(zhuǎn)換。
**函數(shù)結(jié)構(gòu):**toPrimitive(input, preferedType?)
參數(shù)解釋:
input
是輸入的值,即要轉(zhuǎn)換的對(duì)象,必選;
preferedType
是期望轉(zhuǎn)換的基本類型,他可以是字符串,也可以是數(shù)字。選填,默認(rèn)為 number
;
執(zhí)行過(guò)程:
如果轉(zhuǎn)換的類型是 number
,會(huì)執(zhí)行以下步驟:
- 如果
input
是原始值,直接返回這個(gè)值; - 否則,如果
input
是對(duì)象,調(diào)用input.valueOf()
,如果結(jié)果是原始值,返回結(jié)果; - 否則,調(diào)用
input.toString()
。如果結(jié)果是原始值,返回結(jié)果; - 否則,拋出錯(cuò)誤。 如果轉(zhuǎn)換的類型是
string
,2和3會(huì)交換執(zhí)行,即先執(zhí)行toString()
方法。
valueOf 和 toString 的優(yōu)先級(jí):
- 進(jìn)行對(duì)象轉(zhuǎn)換時(shí)
(alert(對(duì)象))
,優(yōu)先調(diào)用toString
方法,如沒(méi)有重寫(xiě)toString
將調(diào)用valueOf
方法,如果兩方法都不沒(méi)有重寫(xiě),但按Object
的toString
輸出。 - 進(jìn)行強(qiáng)轉(zhuǎn)字符串類型時(shí)將優(yōu)先調(diào)用
toString
方法,強(qiáng)轉(zhuǎn)為數(shù)字時(shí)優(yōu)先調(diào)用valueOf
。 - 在有運(yùn)算操作符的情況下,
valueOf
的優(yōu)先級(jí)高于toString
。
由此可知,若 x 為對(duì)象時(shí),我們改寫(xiě) x 的 valueOf 或 toString 方法可以讓標(biāo)題的等式成立:
const x = { val: 0, valueOf: () => { x.val++ return x.val }, }
或者:
const x = { val: 0, toString: () => { x.val++ return x.val }, }
給對(duì)象 x 設(shè)置一個(gè)屬性 val 并賦值為 0,并修改其 valueOf、toString 方法,在 “x == 1 && x == 2 && x == 3”判斷執(zhí)行時(shí),每次等式比較都會(huì)觸發(fā) valueOf、toString 方法,都會(huì)執(zhí)行 val++ ,同時(shí)把最新的 val 值用于等式比較,三次等式判斷時(shí) val 值分別為 1、2、3 與等式右側(cè)的 1、2、3 相同,從而使等式成立。
到此這篇關(guān)于JavaScript中如何讓 x == 1 && x == 2 && x == 3 等式成立的文章就介紹到這了,更多相關(guān)JS 讓 x == 1 && x == 2 && x == 3 成立內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Javascript 調(diào)用 ActionScript 的簡(jiǎn)單方法
在Flex中,ActionScript調(diào)用Javascript是比較簡(jiǎn)單的,說(shuō)白了就是,在html里,怎么調(diào)用Javascript,在ActionScript就怎么調(diào)用就可以了。接下來(lái)通過(guò)本文給大家介紹js 調(diào)用 actionscript方法,感興趣的朋友一起看看吧2016-09-09JavaScript async&await方法中的異常處理方案
在 async/await 方法中,可以使用 try-catch 塊來(lái)處理異常,通過(guò)使用 try-catch,可以捕獲異步操作中拋出的異常,并在 catch 塊中進(jìn)行適當(dāng)?shù)奶幚?本文給大家詳細(xì)介紹了async&await方法中異常如何處理,需要的朋友可以參考下2023-08-08一個(gè)JavaScript防止表單重復(fù)提交的實(shí)例
防止重復(fù)表單提交的方法有很多,本文使用JavaScript來(lái)實(shí)現(xiàn)防止表單重復(fù)提交,很簡(jiǎn)單,但很實(shí)用,新手朋友們不要錯(cuò)過(guò)2014-10-10javascript 動(dòng)態(tài)參數(shù)判空操作
在做交友中心的頁(yè)面的時(shí)候,有一個(gè)javascript函數(shù),它的第二個(gè)參數(shù)是動(dòng)態(tài)的。2008-12-12JS模仿騰訊圖片站的圖片翻頁(yè)按鈕效果完整實(shí)例
這篇文章主要介紹了JS模仿騰訊圖片站的圖片翻頁(yè)按鈕效果,涉及javascript動(dòng)態(tài)操作頁(yè)面元素屬性的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2016-06-06用javascript實(shí)現(xiàn)自動(dòng)輸出網(wǎng)頁(yè)文本
這篇文章主要介紹了用javascript實(shí)現(xiàn)自動(dòng)輸出網(wǎng)頁(yè)文本,用到兩個(gè)函數(shù):setTimeout(),遞歸和String.substring();,需要的朋友可以參考下2015-07-07