JavaScript的执行过程

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()时的情况
JavaScript的执行过程_第1张图片

隐式原型"_proto_"也是[[prototype]]
每个函数function都有一个prototype,即原型。这里再加一句话------每个对象都有一个_proto_,可成为隐式原型。这个_proto_是一个隐藏的属性,javascript不希望开发者用到这个属性值,有的低版本浏览器甚至不支持这个属性值。

每个对象都有一个_proto_属性,指向创建该对象的函数的prototype。

JavaScript的执行过程_第2张图片

同样自定义函数的prototype。自定义函数的prototype本质上就是和 var obj = {} 是一样的,都是被Object创建,所以它的_proto_指向的就是Object.prototype。

但是Object.prototype确实一个特例------它的_proto_指向的是null,切记切记!

同样之前说了函数也是对象,那么函数的_proto_是谁?是Function.prototype,而Function.prototype指向的对象也是对象,它的_proto_是不是也指向Object.prototype?看一张大图慢慢理解:
JavaScript的执行过程_第3张图片
其实在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;

}

你可能感兴趣的:(javascript,this,context)