惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

D
Darknet – Hacking Tools, Hacker News & Cyber Security
Jina AI
Jina AI
博客园_首页
J
Java Code Geeks
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 司徒正美
Hugging Face - Blog
Hugging Face - Blog
S
SegmentFault 最新的问题
MyScale Blog
MyScale Blog
P
Proofpoint News Feed
L
Lohrmann on Cybersecurity
Forbes - Security
Forbes - Security
大猫的无限游戏
大猫的无限游戏
Vercel News
Vercel News
Y
Y Combinator Blog
Google DeepMind News
Google DeepMind News
The Register - Security
The Register - Security
N
News | PayPal Newsroom
S
Security Archives - TechRepublic
量子位
Cisco Talos Blog
Cisco Talos Blog
V
V2EX
C
Cisco Blogs
The Cloudflare Blog
Stack Overflow Blog
Stack Overflow Blog
L
LangChain Blog
Scott Helme
Scott Helme
S
Securelist
Security Latest
Security Latest
爱范儿
爱范儿
TaoSecurity Blog
TaoSecurity Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
I
Intezer
L
LINUX DO - 最新话题
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
C
Check Point Blog
C
CXSECURITY Database RSS Feed - CXSecurity.com
美团技术团队
Know Your Adversary
Know Your Adversary
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
PCI Perspectives
PCI Perspectives
月光博客
月光博客
T
Tailwind CSS Blog
Cloudbric
Cloudbric
小众软件
小众软件
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
K
Kaspersky official blog
D
DataBreaches.Net
博客园 - 【当耐特】
有赞技术团队
有赞技术团队

博客园 - 老苏

(转).NET 3.5新特性 在 .NET Framework 2.0 中未处理的异常导致基于 ASP.NET 的应用程序意外退出 转:理解javascript中的delete机制(3) 转:理解javascript中的delete机制(2) Java NIO类库Selector机制解析(上) VSS 2005 复位 工作目录(Reset Working Folder) 读写XML(1)-关于Dom4j 生成xml文件,以及格式化的xml文件的样例 - 老苏 - 博客园 SWT Display.getDefault() 和Display.getCurrent()的区别 网页纯JS日期时间控件 网页打印2-打印界面实现 A4纸网页打印中对应像素的设定和换算 axman 的专栏,专业,真专业 在ASP.NET 2.0中实现本地化 取消XP的视频预览功能 WEB程序员也要学习学习安全防护(一) 用Delphi编写ASP的ActiveX 兼容性 无提示关闭窗口 为何 .NET 总是BUG不断? 2005年的春天
转:理解javascript中的delete机制(1)
老苏 · 2010-05-17 · via 博客园 - 老苏

在javascript中,我们有时候要使用delete删除对象。但是,对于delete的一些细节我们未必尽知。昨天,看到kangax分析delete的文章,获益匪浅。本文将文章的精华部分翻译出来,与各位分享。

  1. 原理
    1. 代码类型
    2. 执行上下文
    3. 激活对象/可变对象
    4. 属性特性
    5. 内置对象和DontDelete
    6. 未声明的赋值
  2. Firebug 困惑
    1. 通过eval删除变量
  3. 浏览器兼容性
    1. Gecko DontDelete bug
  4. IE bugs
  5. 误区
  6. ‘delete’和宿主对象
  7. ES5严格模式
  8. 总结

原理

为什么我们能删除一个对象的属性?

1 var o = { x: 1 }; 
2 delete o.x; // true 
3 o.x; // undefined

但是,像这样声明的变量则不行:

1 var x = 1
2 delete x; // false 
3 x; // 1
4 
5 

或者如此声明的函数:

1 function x(){} 
2 delete x; // false 
3 typeof x; // "function"
4 
5 

注意,当一个属性不能被删除时,delete只返回false。

要理解这一点,我们首先需要掌握像变量实例化和属性特性这样的概念--遗憾的是这些在关于javascript的书中很少讲到。我将在接下来的几个段落中试着简明的重温这些概念。 理解它们一点也不难,如果你不在乎它们为什么这么运行,你可以随意的跳过这一章。

代码类型

在ECMAScript中有三种类型的可执行代码:全局代码(Global code)函数代码(Function code)Eval code。这些类型有那么点自我描述,但这里还是作一个简短的概述:

  1. 当一段源代码正文被视为程序时,它在全局作用域中执行,被当成全局代码(Global code)。在一个浏览器环境中,SCRIPT元素中的内容通常被当作程序来解析,因此,它被当作全局代码来评估。
  2. 在一个函数内部直接执行的任何代码,很明显被当作函数代码(Function code)。在浏览器红中事件属性的内容(如:<p onclick="...">)通常被当作函数代码(Function code)来解析;
  3. 最后,提供给内置函数eval()的文本被当作Eval 代码(Eval code)来解析。我们很快会看到这种类型很特殊。

执行上下文

当ECMAScript 代码执行时,它总是在一定的上下文中运行,执行上下文是一个有点抽象的实体,它有助于我们理解作用域和变量实例化如何工作的。对于三种类型的可执行代码,每个都有执行的上下文。当一个函数执行时,可以说控制进入到函数代码(Function code)的执行上下文。全局代码执行时,进入到全局代码(Global code)的执行上下文。

正如你所见,执行上下文逻辑上来自一个栈。首先可能是有自己作用域的全局代码,代码中可能调用一个函数,它有自己的作用域,函数可以调用另外一个函数,等等。即使函数递归地调用它自身,每一次调用都进入一个新的执行上下文。

激活对象/可变对象

每一个执行上下文在其内部都有一个所谓的可变对象。与执行上下文类似,可变对象是一个抽象的实体,一个描述变量示例化的机制。现在,最有趣的是在源代码中声明的变量和函数被当作这个可变对象的属性被添加。

当控制进入全局代码的执行上下文时,一个全局对象用作可变对象。这也正是为什么在全局范围中声明的变量或者函数变成了全局对象的属性。

代码

1 /* remember that `this` refers to global object when in global scope */
2   var GLOBAL_OBJECT = this
3   var foo = 1
4   GLOBAL_OBJECT.foo; // 1 
5   foo === GLOBAL_OBJECT.foo; // true   
6   function bar(){} 
7   typeof GLOBAL_OBJECT.bar; // "function" 
8   GLOBAL_OBJECT.bar === bar; // true

Ok,全局变量变成了全局对象的属性,但是,那些在函数代码(Function code)中定义的局部变量又会如何呢?行为其实很相似:它成了可变对象的属性。唯一的差别在于在函数代码(Function code)中,可变对象不是全局对象,而是所谓的激活对象。每次函数代码(Function code)进入执行作用域时,激活对象即被创建。

不仅函数代码(Function code)中的变量和函数成为激活对象的属性,而且函数的每一个参数(与形参相对应的名称)和一个特定Arguments 对象(Arguments )也是。注意,激活对象是一种内部机制,不会被程序代码真正访问到。

代码

 1 (function(foo){ 
 2   var bar = 2
 3   function baz(){} 
 4   /* 
 5   In abstract terms, 
 6   Special `arguments` object becomes a property of containing function's Activation object: 
 7     ACTIVATION_OBJECT.arguments; // Arguments object 
 8   ...as well as argument `foo`: 
 9     ACTIVATION_OBJECT.foo; // 1 
10   ...as well as variable `bar`: 
11     ACTIVATION_OBJECT.bar; // 2 
12   ...as well as function declared locally: 
13     typeof ACTIVATION_OBJECT.baz; // "function" 
14   */
15 })(1);

最后,在Eval 代码(Eval code)中声明的变量作为正在调用的上下文的可变对象的属性被创建。Eval 代码(Eval code)只使用它正在被调用的哪个执行上下文的可变对象。

代码

 1 var GLOBAL_OBJECT = this
 2 /* `foo` is created as a property of calling context Variable object, 
 3     which in this case is a Global object */
 4 eval('var foo = 1;'); 
 5 GLOBAL_OBJECT.foo; // 1 
 6 (function(){ 
 7   /* `bar` is created as a property of calling context Variable object, 
 8     which in this case is an Activation object of containing function */
 9   eval('var bar = 1;'); 
10   /* 
11     In abstract terms, 
12     ACTIVATION_OBJECT.bar; // 1 
13   */
14 })();

未完待续...