ECMAScript 报告(下)

阅读数:557 发布时间:2016-09-28 22:45:28

作者:w4gyc 标签: ECMA

ECMAScript 报告(下)

五、Object.prototype.constructor

Object.prototype有一个属性constructor.

img11

这个constructor是什么呢?来举个例子吧。

img12

我们创建了一个Object的实例a,这个a继承了Object.prototype里的所有属性。于是就有a.constructor === Object.prototype.constuctor ( 严格等于 )

a.constructor 又等于创建 a 的这个构造器。我们可以得出这么一个结论:

一个函数的prototype.constructor默认指向这个函数本身,当我们用new表达式时,首先调用了这个函数的prototype.constructor方法。 但这只是默认情况,实际上出现了反例!我们来看一下cf和它的实例c1

img13

作为c1继承了cf.prototype。所以c1.constructor === cf.prototype.constructor是成立的。但是cf.prototype.constructor指向的却不是cf了,返回了false。

这是为什么呢?因为我们重写了cf.prototype,使它成为了一个Object的实例,所以它的属性也发生了改变。constructor指向变成了Object.

img14

于是我们可以得出结论。每个对象有一个constructor属性,这个属性始终指向构造它的函数。

我们把再cf改动一下,让它更复杂一点。给它加个参数。

     function cf(x){
       this.x = x;
     };

现在我们来剖析一下c1是如何被创建的。

  1. 首先,调用cf.prototype.constructor这个方法 可以表示如下;

img15

此时c1 变成了一个空对象

  1. 把cf.prototype里的属性传递给c1,注意这里的传递是以指针的形式,而不是复制。可以表示如下(仅仅是表示)

img16

此时 c1 拥有了cf.prototype里的属性

3. 以c1作为参数this,执行cf(),可以表示如下

这时候的 c1就是一个完整的cf的实例了。这样,我们模拟实现了构造器的过程,以上就是new这个操作符所做的事情 。

六、作用域和作用域链

1、执行上下文

  1. 什么是执行上下文?执行上下文又叫执行环境,是阐述ECMAScript如何执行代码的一套体系,一个机制。它在可以逻辑表示为一个Stack。
  2. 执行上下文的产生和运作:当进入可执行代码时,即产生了执行上下文。下面举例说明: 源代码

img17

当进入<script>时,即产生了执行上下文,我们可以用ECStack来代表它。ECStack建立后,首先进入的是全局代码,push一个全局环境 global Context,同时建立一个与之相关的变量对象。这个变量对象是可以看作一个哈希表,这个表中存放与它相关的可执行上下文的This,变量、函数声明,参数。

上面的代码,首先创建Global Context,它的变量对象可以表示如下(this保存的触发此环境的对象,arguments保存参数,全局环境没有)

Global Context:{
this: window,
a: 'a',
b: 'b',
c: funA() ,
funA();<pointer>
}

之后创建funA的变量对象

funA:{
this:window,
a: 'aa',
arguments: []
}

每个函数在创建时都会生成一个内部属性[[scope]],这个属性的值是一个词法环境类型。词法环境由环境记录和外部环境指针组成。这个属性是静态的。 每个执行环境会关联到一个作用域链。

相关文章推荐: