简谈JS的原型链和作用域链

谈起js的原型链和作用域链,我觉得还是和图结合起来说比较明白,手绘了一些图片,

原型链

创建一个函数及调用构造函数创建实例的背后

当我们创建了一个新函数时,都会自动为该函数创建一个prototype属性,这个prototype属性是一个指针,指向这个函数的原型对象。而这个原型对象会自动创建一个constructor属性,constructor也是一个指针,指向prototype属性所在的那个函数,即我们创建的那个新函数。
当我们以new形式调用我们刚刚创建的那个函数时(即是以构造函数调用,可以把我们刚刚创建的那个函数理解为类,尽管js本身没有类的概念),我们创建了一个实例,这个实例内部有一个[[Prototype]]指针,指向构造函数的原型对象,即constructor所在的对象。(我们可以通过proto属性访问这个[[Prototype]],也可以通过Object.getPrototypeOf()来访问)

这里写图片描述

重写原型对象

重写函数的原型对象后,函数的prototype指向新的对象,而之前创建的实例的[[prototype]]指向的对象没有改变,尽管这个对象的constructor仍然指向函数,但是当前函数的原型对象和实例之间已经没有联系了。

这里写图片描述

继承中的原型链及默认的原型对象

直接上图就好了,,,

这里写图片描述

作用域链

每个执行环境都有一个与之关联的变量对象,环境中所有的变量和函数都保存在这个变量对象里面。这个变量对象虽然我们无法访问,但是解释器会在后台使用。
当代码在一个环境中执行时,会创建变量对象的一个作用域链,作用域链的前端始终是当前执行的代码所在环境的变量对象,下一个变量对象来自外部包含环境,一直延伸到全局执行环境。
每个函数都有自己的执行环境,当执行到一个函数时,该函数的环境被推入一个环境栈,函数执行后将其弹出。

作用域链与闭包有着密切的关系

作用域链实质上是一个指向变量对象的指针列表。
闭包,简单说就是有权访问另一个函数作用域中变量的函数(一整句话感觉还是觉得比较绕,分开说就是:闭包是一个函数,它不仅能够访问自己作用域中的变量,还能访问另一个函数作用域中的变量)。闭包常见的创建方式是在一个函数中返回另一个函数。

function Outer() {
    var a = 5;
    return function() {
        console.log(a);
    }
}
var fun = Outer();
fun();

如上,即使这个内部函数被返回了,而且是在全局调用的,但是它仍然可以访问变量a。这是因为内部函数的作用域链中包含了外部函数Outer()的作用域。

函数被调用时发生了什么?
1. 创建一个执行环境
2. 创建作用域链
3. 使用arguments及其他命名参数初始化活动对象

举个例子:

function add(a, b) {
    return a + b;
}
var value = add(1, 2);

以这个简单的函数为例子,画出执行环境及作用域链图:

这里写图片描述

创建add函数时,会创建一个预先包含全局变量对象的作用域链,这个作用域链保存在函数内部的[[Scope]]属性中。
当调用add()时,会为函数创建一个执行环境,然后复制函数[[Scope]]属性中的对象构建执行环境的作用域链,之后函数的活动对象被创建并推入执行环境作用域的前端。

正常情况下,函数执行完毕后,局部活动对象被销毁,内存中仅保存全局执行环境的变量对象,但是闭包的情况有所不同。
在一个函数内部创建的另一个函数,会将外部函数的活动对象添加到它的作用域链中,以我们第一段代码为例子。Outer()中定义并返回了一个匿名函数,这个匿名函数的会将Outer()的活动对象添加到自己的作用域链中。当匿名函数被返回后,它的作用域链包含Outer()函数的活动对象和全局变量对象,所以这个匿名函数可以访问Outer()中的变量,即使他是在全局调用的。Outer()在执行完毕后,其执行环境的作用域链会被销毁,但是它的活动对象不会被销毁,因为匿名函数的作用域链仍在引用这个活动对象。

这里写图片描述

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值