ecma262是什么

ECMA-262是ECMAScript5.1的规范。 规范文档描述了ECMAScript的原理、相关定义、规则、标准。 要精通javascript,必须要能够读懂该规范的对应内容。 与《你不知道的javascript上》、《你不知道的javascript中》、《javascript高级程序设计》、《javascript权威指南》对比之后发现,

ECMA-262是ECMAScript5.1的规范。

规范文档描述了ECMAScript的原理、相关定义、规则、标准。

要精通javascript,必须要能够读懂该规范的对应内容。

与《你不知道的javascript上》、《你不知道的javascript中》、《javascript高级程序设计》、《javascript权威指南》对比之后发现,所有的这些书籍,讲的都不太对,都有问题,都不能引入正确的理解。它们在某种程度上能让我们解决遇到的一些问题,但是始终不是描述本质,当遇到更深入的问题时,就没办法了。

所以最终只能到ECMA-262上寻求答案。

但是该规范描述非常抽象、笼统,非常难于理解。

所以,需要加上一些更具体的理解。

 

比如、全局词法环境的环境记录是 声明式记录项还是对象式记录项?规范中没有明说。

比如、词法环境和变量环境一开始是同一个词法环境对象,那什么时候不是同一个词法环境,这个时候他们各自又是什么?

更具体的,为什么在全局执行环境下的代码,var hello = ‘kitty’;console.info(this.hello);会输出kitty?

为什么在全局执行环境下的代码,this.foo = ‘bar’;console.info(foo);会输出bar?

能否在非全局执行环境实现这样的效果?

 

以下,就是本人根据规范、网上博客以及个人理解得出来的一下结论:

全局词法环境的环境记录项是对象式环境记录项,该环境记录项绑定了全局对象(浏览器环境下是window)。所以可以直接访问parseInt。

全局执行环境的this绑定了全局对象(浏览器环境下是window)。所以在全局执行环境的代码this.parseInt是存在的。

执行new、执行函数时,创建的词法环境的环境记录项,都是声明式环境记录项。

执行with时,创建的是对象式环境记录项。

执行with时,会创建新的词法环境,当前执行环境的词法环境,会指向这个新的词法环境。(新的词法环境的外部词法环境,是之前的那个词法环境)

各种书籍、博客上说的作用域,在规范中并没有起专门的章节去说明。也就是说它在规范中有更好的术语表示或者说明。这个术语就是词法环境。更准确的说,是变量环境形成的词法环境链。

变量提升的意义,在于保证把声明的变量和函数绑定在词法环境的声明式环境记录项,而不会绑定到之后with创建的词法环境的对象式环境记录项。

定义绑定初始化遇到函数定义时,会将当前变量环境作为函数对象的[[scope]]属性,将形参作为[[formalParameters]]属性。

函数执行时,根据实参和函数对象的[[formalParameters]]属性,创建Argument对象。该Argument对象被绑定到当前执行环境的变量环境的环境记录项中的argument。

当前执行环境搜索标识符时,都是从它的词法环境获取的。

this不是从词法环境取的,this是执行环境的组件。

this实际上是动态作用域的实现,而不是词法作用域的实现。

 

举个实际的例子

function test(){
with(this){
var tt = 'tt';
console.info(this.tt);//undefined
}
}
new test();
var aaa = 'aaa'
console.info(this.aaa) //aaa
/**
 * 解释:执行代码之前,解释器会先创建一个 全局对象window,一个唯一的全局词法环境,这个全局词法环境的环境记录项的类型为 对象式环境记录项,这个对象式环境记录项 绑定了全局对象。
 * 然后创建全局执行环境,它的this绑定全局对象window,它的词法环境 指向 全局词法环境,它的 变量环境 指向 全局词法环境。
 * 所以,在全局执行环境,代码中的this,就是window。var一个变量时,这个变量会添加到全局执行环境的变量环境,由于该变量环境是对象式变量环境,绑定的是window对象,所以声明的变量,会成为window的属性。
 * 所以有 console.info(this.aaa)输出aaa
 * 
 * 那为什么console.info(this.tt);输出的是undefined
 * 执行new test()时,会创建一个新的执行环境(test-executeContext),该执行环境有一个词法环境,变量环境,this。
 * test-executeContext的词法环境是一个新的词法环境对象(test-lex),它是一个声明式词法环境,它的外部词法环境是全局词法环境。它的环境记录项绑定了标识符tt。
 * test-executeContext的变量环境和test-executeContext的词法环境一开始指向同一个词法环境对象。
 * 执行with语句时,会创建一个新的词法环境(with-lex),它是一个对象式词法环境,绑定了new test()创建的对象(test-instance)。在其中声明的变量,都会作为test-instance的属性。
 * 但是!!!js中有一个技术叫做变量提升技术。上面的变量tt,实际上属于test-lex,而不属于with-lex。所以tt不会成为test-instance的属性。
 * 我们没法像全局环境一样,var一个变量,它会成为this引用的对象的属性!
 * */
this.bb  = 'bb';
console.info(bb);

 

 

知秋君
上一篇 2024-07-20 20:12
下一篇 2024-07-20 19:48

相关推荐