一、原型链
1、 建立一个构造函数
function Person(name){
this.name = name
}
var person = new Person('LiPei');
输出的是
2、有关原型链
在JavaScript中,每当定义一个函数数据类型(普通函数、类)时候,都会天生自带一个prototype属性,这个属性指向函数的原型对象,并且这个属性是一个对象数据类型的值。 js对象中除了null以外都有一个原型对象,就上述的构造函数而言就是person实例的原型。 整体的关系图如下:
构造函数.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
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)
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)
当在读取实例属性时,如果找不到的话就会去查找与对象关联的原型中的属性,如果还找不到就会去找原型的原型,一直找到最顶层为止。上面关系图中的蓝线部分组成的链式结构就是原型链。原型链最后会的原型对象是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()
这样向上找的过程的作用域集合形成作用域链。
三 、原型链和作用域链之间的区别
1、作用域最顶层是window ,原型链最顶层是Object
2、作用域链作用在普通函数的作用域上,操作的是变量(全局变量和局部变量);原型链作用的是原型链作用在构造函数上,原型链操作构造函数的属性:实例属性和原型属性,往构造函数构成的原型链向上寻找的过程。
参考文献:
[1](理解Javascript的作用域和作用域链 - 掘金 (juejin.cn))
[2]((31条消息) 作用域链与原型链_HelloGad的博客-CSDN博客_作用域链顶层)