獲取函式中某個區域性變數物件種的所有key值?
阿新 • • 發佈:2018-12-15
題目
在不改變以下程式碼的情況下,如何獲取函式fn
中區域性變數obj
中所有鍵值?
function fn (key) {
const obj = { a: 1, b: 2, /* other props */ }
return obj[key];
}
分析
可以看出obj會呼叫其某個key獲取其值,而根據this上下文的原理,如果通過obj呼叫某個函式,那麼this能夠直接獲取到obj物件,然後就可以通過Object.keys(this)
獲取到obj的所有鍵值。
而題目中只是通過key去獲取該屬性的值,並沒有呼叫什麼函式。那麼這裡就應該想到通過Object.defineProperty
return Object.keys(this)
,如下:
var obj = {a: 1, b: 2};
Object.defineProperty(obj, 'somekey', {
get () { return Object.keys(this) }
});
obj.somekey // ['a', 'b']
但是按照題目的要求,我們能直接劫持obj,那麼這裡就需要利用到原型鏈的原理。假定obj上沒有'somekey'
,那麼就會在其原型鏈上查詢,即Object.prototype
上查詢該屬性。那麼我們可以直接劫持Object.prototype
'somekey'
。
但問題就在於如何保證這個'somekey'
在obj上面不存在?— Symbol
!
解答
let key = Symbol();
Object.defineProperty(Object.prototype, key, {
get () { return Object.keys(this) }
});
fn(key); // ['a', 'b', /* other props */]
番外篇
當然還有一個騷操作—通過fn.toString
獲取到函式內容的字串,然後通過正則去匹配。