通俗理解之JS -- 原型链和作用域链以及两者区别

517 阅读2分钟

一、原型链

1、 建立一个构造函数
 function Person(name){
            this.name = name
        }
        var person = new Person('LiPei');

输出的是

6d23b03cbbd27e8fa39071bd487ce4a.png

2、有关原型链

在JavaScript中,每当定义一个函数数据类型(普通函数、类)时候,都会天生自带一个prototype属性,这个属性指向函数的原型对象,并且这个属性是一个对象数据类型的值。 js对象中除了null以外都有一个原型对象,就上述的构造函数而言就是person实例的原型。 整体的关系图如下:

prototype5.png 构造函数.prototype直接指向实例原型,若是构造函数下的实例的话就是,实例.__proto__指向实例原型,实例原型.constructor则指向构造函数。

function Person(name){
            this.name = name
        } 
        var person = new Person('LiPei');
        console.log(person.__proto__ == Person.prototype) // true
        console.log(Person.prototype.constructor == Person) // true
        console.log(Object.getPrototypeOf(person) === Person.prototype) // true

1404156c742aa1fa6a0d54e9f9e2c83.png

function Person(name){
            this.name = name
        }
        function Fperson(name){
            this.name = name
        }
        console.log('Person.prototype',Person.prototype)
        Person.prototype = new Fperson('Fperson')
        console.log('Person.prototype2',Person.prototype)

c7ffecf51334fb23f3ef09dbba19a2f.png

function Person(name){
            this.name = name
        }
        function Fperson(name){
            this.name = name
        }
        Person.prototype = new Fperson('Fperson')
        var person = new Person('LiPei');
        console.log('person',person.name)
        delete person.name
        console.log('person',person.name)

68e1e84663ee6921ab5b4128f88996f.png 当在读取实例属性时,如果找不到的话就会去查找与对象关联的原型中的属性,如果还找不到就会去找原型的原型,一直找到最顶层为止。上面关系图中的蓝线部分组成的链式结构就是原型链。原型链最后会的原型对象是Object,Object最终会指向null 即原型链的终点。

3、 作用

实现继承,就是子类继承父类的方法和变量;原型上可以定义一些方法和变量;以这个原型建立的对象,可以使用原型方法和变量,从而实现继承。

二、 作用域链

当在Javascript中使用一个变量的时候,首先Javascript引擎会尝试在当前作用域下去寻找该变量,如果没找到,再到它的上层作用域寻找,以此类推直到找到该变量或是已经到了全局作用域。如果在全局作用域里仍然找不到该变量,它就会在全局范围内隐式声明该变量(非严格模式下)或是直接报错。

let a = 'aaa'
        function func (){
            let b = 'bbbb'
            console.log('b',b);
            console.log('a',a);
            console.log('c',c)

        }
        func()

821b3526a17ea0f86c63fe72aa5e11a.png 这样向上找的过程的作用域集合形成作用域链。

三 、原型链和作用域链之间的区别

1、作用域最顶层是window ,原型链最顶层是Object
2、作用域链作用在普通函数的作用域上,操作的是变量(全局变量和局部变量);原型链作用的是原型链作用在构造函数上,原型链操作构造函数的属性:实例属性和原型属性,往构造函数构成的原型链向上寻找的过程。

参考文献: [1](理解Javascript的作用域和作用域链 - 掘金 (juejin.cn))
[2]((31条消息) 作用域链与原型链_HelloGad的博客-CSDN博客_作用域链顶层)