2011-12-24 81 views
4

我使用谷歌瀏覽器16.0.912.63及有以下代碼:爲什麼未定義的行爲與其他變量不同?

__defineGetter__('x', function(){ 
    console.log('In Getter: x'); return 1; 
}); 

__defineGetter__('undefined', function(){ 
    console.log('In Getter: undefined'); return 2; 
}); 

console.log(x); 
console.log(undefined); 

輸入正確的x吸氣功能,但從未進入未定義的吸氣劑。登錄到我的控制檯輸出爲:

In Getter: x 
1 
undefined 

我一直的印象是undefined的行爲與其他任何全局變量下。我知道,語句如

undefined = 10; 
undefined = null; 
undefined = 'defined'; 

都是有效的,那麼什麼是不同的關於undefined,使得它無法擁有(在我的瀏覽器至少)的吸氣劑。

JSFiddle

+1

它不適用於jsFiddle,但它在粘貼到控制檯時可以正常工作。 – pimvdb 2011-12-24 21:26:31

+1

@pimvdb:這是因爲控制檯評估的代碼被封裝在一個'with(console)'塊中,因此它定義了一個屬性'console.undefined'。 – Ryan 2011-12-24 21:28:40

回答

3

它不表現得像任何正常的變量,它只是假裝,至少在Firefox和Chrome。試試看:

var x; 
undefined = "Hello!"; 
x === undefined; // true; undefined doesn't change 

它更像是隻讀屬性,但寫入時不會拋出錯誤。

+1

這似乎是一個有趣的方式來介紹調試挫折... = /哦,和+1回答我從來沒有想過要問的問題。 =) – 2011-12-24 21:27:47

+0

在Chrome上返回false ... – pimvdb 2011-12-24 21:28:27

+0

@pimvdb:我在Chrome上測試,它評估爲'true' ... – Ryan 2011-12-24 21:29:49

2

看來__defineGetter__只是默默地失敗。 Object.defineProperty拋出一個錯誤:

redefine_disallowed 

當你調用這個在Chrome:

Object.defineProperty(window, "undefined", { 
    get: function() { 
     return 2; 
    } 
}); 

在另一方面:

window.__defineGetter__("undefined", function() { 
    return 2; 
}); 

window.__lookupGetter__("undefined"); // undefined, so __defineGetter__ just ignored call 

爲什麼它在Chrome的控制檯:

當你d efine 一次性獲得undefined粘貼在控制檯中的代碼時,它的工作原理,因爲有幕後的一些功能正在執行其使用with塊參照console._commandLineAPI

if (injectCommandLineAPI && inspectedWindow.console) { 
    inspectedWindow.console._commandLineAPI = new CommandLineAPI(
     this._commandLineAPIImpl, 
     isEvalOnCallFrame ? object : null 
    ); 
    expression = "with ((window && window.console && window.console._commandLineAPI) || {}) {\n" + expression + "\n}"; 
} 
return evalFunction.call(object, expression); 

所以你只是定義了console._commandLineAPI.undefined

另一點是,它覆蓋console._commandLineAPI(見上面的代碼),所以如果你定義和它不工作得到undefined爲兩個命令,因爲吸氣劑已經被您嘗試獲取undefined時扔掉由覆蓋。

此外,它不會覆蓋window.undefined,這很可能是它在控制檯中的原因。

+0

嗯......有趣。那麼,'__ * etter__'方法由於我認爲的原因而被棄用:) +1 – Ryan 2011-12-24 21:37:14

相關問題