javascript的执行过程
整个JavaScript的代码运行可以分为 <建立执行上下文> 和 <代码执行> 两个阶段;
其中执行上下文的建立包括:
- 初始化this
- 变量对象VO(活动对象AO)
- 作用域链SC;
代码执行时会实例化VO或AO对象中的变量;具体如下:
执行上下文 execution context
执行上下文会有三种情况:
- 全局执行上下文、
- 函数执行上下文、
- eval执行上下文;
引擎会在执行时建立执行上下文堆栈;执行上下文会初始化三个对象:this、变量对象VO/活动对象AO、作用域链。
this对象
使用easy模式来判定this的指向,作为对象属性方法调用时指向对象,作为全局方法使用指向window,函数中的this主要是依赖于调用者,在进行赋值等操作时注意this的指向丢失问题;
变量对象VO/激活对象AO
看有些资料说变量对象和活动对象是一回事儿,甚至有些资料说其差异在于活动对象多了arguments属性。昨天的学习课程让我对这个问题有了清晰的认识。变量对象实际上是一个逻辑上的概念,是逻辑上作用域链的组成元素。而在实际的实践中则大部分时间由活动对象充当这个角色。在全局上下文中,全局对象window充当变量对象,全局上下文的作用域链中存放全局对象;在函数进入执行上下文之前,会生成一个活动对象,将arguments、参数、函数声明、变量声明按这个顺序添加到变量对象之中。
在VO/AO中存在同名变量时的覆盖顺序是:应该是函数声明>函数形参>变量;也就是在这里完成变量声明、函数形参和函数声明的提前的;而变量声明不会进行复制操作,函数形参也没有复制操作一说;需要注意的是函数声明会把函数体带入,此时函数会建立相应的隐式[[scope]]数组属性,这个数组指向的当前上下文的作用域链,需要注意的是这里只有函数声明,不会有函数表达式,函数声明都是在跟语句下,而函数表达式都是在执行代码时建立的;
函数中的激活对象最开始只有一个对象;就是arguments这个对象,有着length、callee等属性;
其实VO/AO都是作为当前上下文的作用于链的组成元素,
作用域链scope chain
全局执行上下文的作用域链就是[window];
函数的作用域链就是 [当前上下文的VO/AO,自身的scope内容];这里函数的隐式[[scope]]是在函数被声明或者被表达式执行时建立的,也就是上文说的当前执行上下文的作用域链;
变量实例化在代码执行前,上下文建立后来完成的
原型
所有的对象都是通过函数创建的,首先看看函数和new操作时都发生了什么:其中隐式[[prototype]]也就是浏览器中认为的 _protp_这个对象
prototype原型
函数也是一种对象。他也是属性的集合,你也可以对函数进行自定义属性。javascript自己就默认的给函数一个属性------prototype。对,每个函数都有一个属性叫做prototype。这个prototype的属性值是一个对象(属性的集合,再次强调!),默认的只有一个叫做constructor的属性,指向这个函数本身。
进行new Object()时的情况
隐式原型"_proto_"也是[[prototype]]
每个函数function都有一个prototype,即原型。这里再加一句话------每个对象都有一个_proto_,可成为隐式原型。这个_proto_是一个隐藏的属性,javascript不希望开发者用到这个属性值,有的低版本浏览器甚至不支持这个属性值。
每个对象都有一个_proto_属性,指向创建该对象的函数的prototype。
同样自定义函数的prototype。自定义函数的prototype本质上就是和 var obj = {} 是一样的,都是被Object创建,所以它的_proto_指向的就是Object.prototype。
但是Object.prototype确实一个特例------它的_proto_指向的是null,切记切记!
同样之前说了函数也是对象,那么函数的_proto_是谁?是Function.prototype,而Function.prototype指向的对象也是对象,它的_proto_是不是也指向Object.prototype?看一张大图慢慢理解:
其实在JavaScript中的instanceof就是跟着原型链这么来进行判定的;
创建function算法 函数有prototype属性是个对象和[[Prototype]]也就是_proto_属性
F=new Object();创建对象
F.[[class]]="Function";指定类型
F.[[Prototype]]=Function.prototype;把_proto_指向函数的prototype
F.[[Call]]=internalCall; 内部调用
F.[[Construct]]=internalConstructor; 内部构造
F.[[Scope]]=currentContext.Scope Chain.concat(); 把[[Scope]]是当前执行上下文作用域
F.length=FormalParameterNum
//DontDelete ReadOnly DontEnum
temp=new Object(); 初始化prototype
temp.constructor=F; 初始化prototype下的constructor
//DontEnum DontDelete
F.prototype=temp; 完成初始化
return F 返回
new函数
function internalConstructor(parameters){
O=new Object();
O.[[Class]]="Object";
O.[[Prototype]]=Object.prototype;
R=F.[[Call]].apply(O,parameters);
return O;
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。