作用域链:【针对标识符解析】
js执行都是在“执行环境“中进行的,最外围是全局执行环境(浏览器中是window对象),当执行流进入一个函数时,函数的环境会被推入环境栈中,函数执行完后,栈将其环境弹出,把控制权返回给之前的执行环境。当代码在一个环境中执行时,会创建VO(变量)对象的一个作用域链。作用域链的用途,是保证对执行环境有权访问的所有变量和函数的有序访问。作用域链的前端,始终都是当前执行代码所在环境的VO。如果这个环境是个函数,则将其AO(活动对象)作为VO。作用域链的下一个VO来自包含(外部)环境,以此类推。
标识符解析是沿着作用域链一级一级地搜索标识符的过程。搜索过程始终从作用域链的前端开始,然后逐级地向后回溯,直至找到标识符为止。
延长作用域链:
try-catch的catch语句、with语句可临时在当前作用域链的前端增加一个VO
try{ }catch(err){ } 创建一个VO,其中包含错误对象
with(o){ } 将指定对象添加到作用域链中
原型链:【针对构造函数】
JavaScript万物都是对象,函数创建时有prototype属性指向原型对象,每个对象实例都有__proto__(隐式原型)属性指向该对象的构造函数的原型对象。在JavaScript中是通过prototype对象指向父类对象,直到指向Object对象为止来实现继承,这样就形成了一个原型指向的链条,此为原型链。
对象实例,构造函数,原型之间的关系如下:(引用网上的图片)
Object.getPrototypeOf(实例)、Object.setPrototypeOf(object,proto) 可操作[[Prototype]]
__proto__也可以获取,mdn不推荐
注意:构造函数和对象实例是不发生关系的
__proto__与prototype的区别:(引用网上的图片)
解释:b,c为对象实例,b、c的__proto__指向其构造函数的原型对象即Foo.prototype。Foo为函数实例,那么Foo的__proto__就指向构造一个普通函数的构造函数(Function)的原型对象即Function.prototype。js里的本地对象都是有Object构造的,所以Function.prototype.__proto__指向Object.prototype。
这里有一点图里没画出来,就是Function又是谁构造出来的呢?
经测试:Function.__proto__ === Function.prototype //true
Function.prototype.__proto__ === Object.prototype //true
网友评论