![](/img/trans.png)
[英]Can someone explain this getOwnPropertyDescriptor and delete behavior?
[英]delete: can someone explain this behavior
比較這段代碼1 :
somevar = 5;
delete window.somevar;
alert(typeof somevar) //=> undefined, so deleted
這段代碼:
var somevar = 5;
delete window.somevar;
alert(typeof somevar) //=> number, so NOT deleted
現在在第一個塊中, somevar
被刪除,在第二個塊中則沒有。 唯一的區別是在第二個塊中使用var
關鍵字。 兩個塊都在全局范圍內運行。
這可以解釋一下嗎?
1代碼不能在chrome-console或firebug中測試,也不能在jsfiddle中測試。 在這些環境中,所有代碼都被evalled
,並且在evalled代碼中, delete
可以處理eval
任何結果(請參閱更多信息 )。 在IE <9中,無論如何都不允許delete window[anything]
。
您所看到的是這樣一個方面:全局對象( window
,瀏覽器)是兩個不同事物的混合,除了全局執行上下文之外,它們在任何地方都是不同的。
在第一個塊中, someVar
是window
對象的普通屬性。 可以通過delete
屬性。
在第二個塊中, someVar
是全局執行上下文的變量上下文的綁定對象的屬性 - 也是window
。 您無法刪除綁定對象在其作為綁定對象的角色中接收的屬性(即使您可以刪除以其他方式接收的屬性)。 也就是說,你不能刪除用var
聲明的變量(以及其他一些以相同方式添加的東西)。
(對不起,不是我的術語;它來自規范 ,確實有一些非常有趣的語言。)
它只是全局執行上下文,我們有這種概念的混合。 其他執行上下文(例如函數調用)的變量綁定對象仍然是一個非常真實的東西(對於閉包的正常運行至關重要),但是沒有直接訪問它的編程方式。 但是,在全局執行上下文中,它是全局對象,當然我們可以訪問它。
如果我們首先查看函數,然后查看全局執行上下文,這有助於理解這一點。 當你調用一個函數時,會發生以下事情:
this
為指向由調用指定對象的值( this
通常是隱式設置,但有辦法來設置它明確)。 arguments
屬性添加到綁定對象,引用函數參數的偽數組。 var
語句聲明的任何變量的名稱(在函數體中的任何位置 )作為綁定對象的屬性,最初使用值undefined
。 ...然后開始逐步執行函數體中的代碼。 任何帶有初始值設定項的var
語句(例如, var a = 5;
而不僅僅是var a;
當執行點到達時,它們被視為賦值語句( a = 5;
)。
綜上所述,只要將屬性添加到“綁定對象”,就會添加一個表示無法刪除的標志。 這就是無法刪除var
s(以及聲明的函數的名稱等)的原因。
通過范圍鏈查找任何不合格的引用。 因此,當您在代碼中引用a
時,解釋器所看到的第一個位置是作用域鏈頂部的綁定對象。 如果它有一個名為a
的屬性,那就是使用它; 如果沒有,我們會查看范圍鏈中的下一個鏈接,並在找到它時使用該屬性; 等等,直到我們用完范圍鏈上的鏈接。 全局對象是該鏈的最底層鏈接(這就是全局變量起作用的原因)。
那么全球背景有什么不同呢? 嗯,實際上很少。 這是序列(大致):
this
指向綁定對象; 這使它成為全球對象。 window
被添加到對象中,引用自身)。 ...然后我們基本上接受了函數中的第8步:
var
語句聲明的任何變量的名稱(在全局范圍內的任何位置 )作為綁定/全局對象的屬性,最初使用值undefined
。 ...並開始逐步執行代碼(再次使用var
初始化程序成為賦值)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.