誤區(qū)
理解事物為什么那么工作是一種難以言說的美,我在網(wǎng)上已經(jīng)看到了與delete 運(yùn)算符誤解相關(guān)的誤區(qū)。例如,在關(guān)于棧溢出的回答(評(píng)分出其不意的效果高)中,它自信的解釋道:“delete is supposed to be no-op when target isn’t an object property ”,F(xiàn)在,我們已經(jīng)理解了delete 行為的核心,很清楚這個(gè)答案是不準(zhǔn)確的。delete 不區(qū)分變量和屬性(事實(shí)上,對(duì)于刪除,這些都是引用),真正的只關(guān)心的是DontDelete特性(和屬性存在)。
非常有意思的看到這個(gè)誤解如何相互影響,在同樣一個(gè)線程中,有人首先提出要直接刪除變量(除非它是在eval 中聲明,否則不會(huì)生效),接著另外一個(gè)人提出一種錯(cuò)誤的糾正方法--在全局中可能刪除變量,但在函數(shù)內(nèi)不行。
在網(wǎng)站上解釋Javascript 最好小心,最好總是抓住問題的核心。
‘delete’和宿主對(duì)象
delete 的算法大概是這樣:
- 如果操作不是一個(gè)引用,返回
true ;
- 如果一個(gè)對(duì)象沒有直接的屬性,返回
true ;(我們知道,對(duì)象可以是激活對(duì)象,可以是全局象);
- 如果一個(gè)屬性存在并有DontDelete特性,返回
false ;
- 否則,刪除屬性并返回
true ;
但是,宿主對(duì)象的delete 運(yùn)算符的行為難以預(yù)測。實(shí)際上并沒有錯(cuò):除了少數(shù)幾個(gè),宿主對(duì)象是允許執(zhí)行任何類型的運(yùn)算行為的(按規(guī)范),如read(內(nèi)部的[get]方法)、write(內(nèi)部的[put]方法)或delete (內(nèi)部的[delete]方法)。這個(gè)定制的[[Delete]]行為使得宿主對(duì)象如此混亂。
在IE中我們已經(jīng)看到一些古怪的行為,如果刪除某些對(duì)象(明顯作為宿主對(duì)象來執(zhí)行)將拋出錯(cuò)誤。Firefox的一些版本在嘗試刪除window.location 時(shí)將拋出錯(cuò)誤。當(dāng)涉及到宿主對(duì)象時(shí),你不能信任delete 返回的任何值?纯丛贔irefox會(huì)有什么發(fā)生:
/* "alert" is a direct property of `window` (if we were to believe `hasOwnProperty`) */
window.hasOwnProperty( 'alert' ); // true
delete window.alert; // true
typeof window.alert; // "function"
刪除window.alert 返回true ,雖然這個(gè)屬性什么也沒有,它應(yīng)該導(dǎo)致這個(gè)結(jié)果。它保留了一個(gè)引用(因此在第一步中不應(yīng)該返回true ),它是窗口對(duì)象的直接屬性(因此第二步中不能返回true)。唯一的辦法讓delete 返回true 是在第四步之后真正刪除屬性。但是,屬性是永遠(yuǎn)不會(huì)被刪除的。
這個(gè)故事的寓意在于永遠(yuǎn)不要相信宿主對(duì)象
ES5嚴(yán)格模式
那么,ECMAScript 5th edition 的嚴(yán)格模式可以拿到臺(tái)面上來了。一些限制正被引入,當(dāng)delete 運(yùn)算符是一個(gè)變量、函數(shù)參數(shù)或函數(shù)標(biāo)識(shí)符的直接引用時(shí)將拋出SyntaxError。另外,如果屬性內(nèi)部有[[Configurable]] == false,將拋出TypeError。 ( function (foo){
"use strict" ; // enable strict mode within this function
var bar;
function baz(){}
delete foo; // SyntaxError (when deleting argument)
delete bar; // SyntaxError (when deleting variable)
delete baz; // SyntaxError (when deleting variable created with function declaration)
/* `length` of function instances has { [[Configurable]] : false } */
delete ( function (){}).length; // TypeError
})();
另外,刪除未聲明的變量(換句話說,沒有找到的引用)也拋出SyntaxError。 "use strict" ;
delete i_dont_exist; // SyntaxError
正如你所理解的那樣,考慮到刪除變量、函數(shù)聲明和參數(shù)會(huì)導(dǎo)致如此多得混淆,所有這些限制就有點(diǎn)意義。與不聲不響的忽略刪除行為相反,嚴(yán)格模式應(yīng)該采取更積極的、更具有描述性的措施。
出處:
責(zé)任編輯:bluehearts
上一頁 理解delete [6] 下一頁 理解delete [8]
◎進(jìn)入論壇網(wǎng)頁制作、WEB標(biāo)準(zhǔn)化版塊參加討論,我還想發(fā)表評(píng)論。
|