删除:有人可以解释这种行为吗?
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控制台或Firebug中测试,也不能在JSFIDDLE中测试。在这些环境中,所有代码都是evalled
的,而在邪恶的代码中,delete
处理任何eval
的结果(请参阅更多内容)。在IE <9中,无论如何都不允许使用delete window[anything]
。
你所看到的是全局对象(浏览器上的window
)是两个不同事物的融合,除了全局执行上下文之外,它们在任何地方都是不同的。
在第一个块中,someVar
是window
对象的正常属性。可以通过delete
删除属性。
在第二个块中,someVar
是全局执行上下文 的变量上下文的绑定对象的属性 — 这也是window
。不能删除绑定对象作为绑定对象的角色接收的属性(即使可以通过其他方式删除它接收的属性)。也就是说,您不能删除用 var
声明的变量(以及以相同方式添加的其他一些内容)。
(对不起,不是我的术语;它来自规范,它确实有一些非常有趣的语言。
只有在全局执行上下文中,我们才有这种概念的合并。其他执行上下文(例如函数调用)的变量绑定对象仍然是一个非常真实的东西(对于闭包的正常运行至关重要),但没有直接访问它的编程方法。但是,在全局执行上下文中,它是全局对象,我们当然可以访问它。
如果我们先查看函数,然后再查看全局执行上下文,则有助于理解这一点。 调用函数时,会发生以下情况:
- 将
this
设置为指向调用指定的对象(this
的值通常是隐式设置的,但有一些方法可以显式设置它)。 - 为此调用创建执行上下文。
- 为该执行上下文创建变量上下文。
- 为该变量上下文创建绑定对象。
- 将函数的名称(如果有)作为引用函数的属性添加到绑定对象中。
- 将
arguments
属性添加到绑定对象,引用函数的参数伪数组。 - 将函数定义中声明的任何命名参数添加为绑定对象的属性,并引用其在参数中的条目。
- 添加通过
var
语句(函数体中的任何位置)声明的任何变量的名称作为绑定对象的属性,最初值为undefined
。 - 如果在函数中声明了命名函数,请将其名称添加为绑定对象的属性,并引用这些函数。
- 将绑定对象放在作用域链的顶部(详见下文)。
。然后开始逐步执行函数主体中的代码。任何带有初始值设定项(例如,var a = 5;
而不仅仅是var a;
的var
语句在执行点到达它们时都被视为赋值语句(a = 5;
)。
在上述内容中,每当将属性添加到"绑定对象"时,都会添加一个标志,指示无法删除该属性。这就是为什么不能删除var
(以及声明的函数的名称等)的原因。
任何非限定引用都通过作用域链进行查找。因此,当您在代码中引用a
时,解释器首先查找的是作用域链顶部的绑定对象。如果它有一个名为 a
的属性,那就是使用的;如果没有,我们查看作用域链下的下一个链接,并在找到该属性时使用该属性;依此类推,直到我们用完作用域链上的链接。全局对象是该链的最底层环节(这就是全局变量工作的原因)。
那么,全球背景有什么不同呢?嗯,实际上很少。这是顺序(大致):
- 为此调用创建执行上下文。
- 为该执行上下文创建变量上下文。
- 为该变量上下文创建绑定对象。
- 将
this
设置为指向绑定对象;这使它成为全局对象。 - 根据环境的定义在该对象上设置一些默认属性(例如,在浏览器中,属性
window
被添加到对象中,引用自身)。
。然后我们基本上从函数中的步骤 8 开始:
- 添加通过
var
语句声明的任何变量的名称(全局范围内的任何位置)作为绑定/全局对象的属性,最初值为undefined
。 - 如果在全局范围内声明了命名函数,请将其名称添加为绑定/全局对象的属性,并引用这些函数。
- 将绑定/全局对象放在作用域链的顶部(更多内容见下文)。
。并开始逐步执行代码(再次将var
初始值设定项变为赋值项)。
- 使用php或javascript从facebook相册URL中删除多余的部分
- RegEx删除空属性?例如,如果(class=“”||class=“”)移除;否则就下课
- 如何删除多行HTML排列中的空白
- 如何从rails中的代码中删除新行( )
- 删除对HTML元素的拖动
- 当图像转换为本地存储的DataURL时,EXIF被删除
- 按顺序添加和删除类
- iframe正在添加标签,需要删除它们
- 如何在HTML输入字段中添加不可删除的后缀
- addData()从最新图表中删除.js 2.1.3-怎么了
- 如何覆盖锚点元素's href目标,并在我点击转到目标javascript时删除其他错误
- 删除CKEditor工具栏按钮,但不删除功能
- 当浏览器上的后退按钮到达主页时,我需要删除Class
- 正在删除node.js中已验证的网站
- 正在从页面中删除iframe
- 如何从 HTML 查询中删除项目
- 如何在iOS应用程序中从Firebase中删除超过6小时的数据
- 未捕获的类型错误:无法读取属性'删除'的未定义
- 删除:有人可以解释这种行为吗?
- 解释用于从字符串中删除 html 代码的正则表达式