- 做者:陳大魚頭
- github: KRISACHAN
- 連接:github.com/YvetteLau/S…
- 背景:最近高級前端工程師 劉小夕 在 github 上開了個每一個工做日佈一個前端相關題的 repo,懷着學習的心態我也參與其中,如下爲個人回答,若是有不對的地方,很是歡迎各位指出。
此題目的答案能夠分爲三大類:javascript
首先咱們要知道,在 JS 中類型轉換隻有三種狀況,分別是:前端
對象在轉換類型的時候,會執行原生方法ToPrimitive。java
其算法以下:git
toSting
方法,若是此時是 原始類型 則直接返回,不然再調用valueOf
方法並返回結果;valueOf
方法,若是此時是 原始類型 則直接返回,不然再調用toString
方法並返回結果;固然,咱們能夠經過重寫Symbol.toPrimitive
來制定轉換規則,此方法在轉原始類型時調用優先級最高。github
因此以此定義咱們能夠有如下四種答案:正則表達式
var a = {
arr: [3, 2, 1],
valueOf () {
console.group('valueOf')
console.log(this.arr)
console.groupEnd('valueOf')
return this.arr.pop()
}
}
if (a == 1 && a == 2 && a == 3) {
console.log('biu')
}
var b = {
arr: [3, 2, 1],
toString () {
console.group('toString')
console.log(this.arr)
console.groupEnd('toString')
return this.arr.pop()
}
}
if (b == 1 && b == 2 && b == 3) {
console.log('biu')
}
var c = {
arr: [3, 2, 1],
[Symbol.toPrimitive] () {
console.group('Symbol.toPrimitive')
console.log(this.arr)
console.groupEnd('Symbol.toPrimitive')
return this.arr.pop()
}
}
if (c == 1 && c == 2 && c == 3) {
console.log('biu')
}
var d = [1, 2, 3]
d.join = d.shift
if (d == 1 && d == 2 && d == 3) {
console.log('biu')
}
複製代碼
魚頭注:事實上,這四種能夠算是同一種。關於最後一種,咱們能夠來看看ECMA中的 Array.prototype.toString ( )
定義:算法
array
爲 ToObject(this value)
(原生方法,將當前數組轉換成對象);func
爲 Get(array, 'join')
(原生方法,在這一步調用 join
方法);IsCallble(func)
(原生方法,判斷是否有內部可調用的函數)爲 false
,則 設置 func
原生函數 %ObjProto_toString%
(原生函數,toString
的具體實現);Call(func, array)
。getter
的劫持所謂的 getter
就是對象屬性在進行查詢時會被調用的方法 get
,利用此函數也能夠實現題目功能。數組
代碼以下:微信
window.val = 0
Object.defineProperty(window, 'd', {
get () {
return ++this.val
}
})
if (d == 1 && d == 2 && d == 3) {
console.log('biu')
}
const e = new Proxy({}, {
val: 1,
get () {
return () => this.val++;
}
});
if (e == 1 && e == 2 && e == 3) {
console.log('biu')
}
複製代碼
JS
中的 RegExp.prototype.exec()
做用是在一個指定字符串中執行一個搜索匹配,返回一個結果數組或 null。前端工程師
當正則表達式使用 "g
" 標誌時,能夠屢次執行 exec
方法來查找同一個字符串中的成功匹配。當你這樣作時,查找將從正則表達式的 lastIndex
屬性指定的位置開始。(test()
也會更新 lastIndex
屬性)。
lastIndex
是正則表達式的一個可讀可寫的整型屬性,用來指定下一次匹配的起始索引。只有正則表達式使用了表示全局檢索的 "g
" 標誌時,該屬性纔會起做用。
魚頭注:只有正則表達式使用了表示全局檢索的 "g
" 標誌時,該屬性纔會起做用。
綜上所述,咱們能夠有方案以下:
var f = {
reg: /\d/g,
valueOf () {
return this.reg.exec(123)[0]
}
}
if (f == 1 && f == 2 && f == 3) {
console.log('biu')
}
複製代碼
魚頭注:上述方法其實也利用了類型轉換的特色。而後暫時就寫下以上三種答案,不知道聰明的你是否還有別的解法呢?