JavaScript 原型链

摘要

  • 原型 prototype ,给继承者继承的对象,只有函数对象拥有
  • 所有对象(函数对象,普通对象)都有一个 __proto__ 的隐式原型属性,用于指向构造他的函数的原型
  • constructor 指向构造他的构造函数

prototype

函数被创建时,都会得到一个 prototype 属性(原型对象),所有原型对象都会默认得到 constructor 属性,指向与之相关的构造函数

function Person() {}
Person.prototype.name = 'xiao ming';
Person.prototype.age  = 18;

console.log(Person.prototype.constructor === Person); // true
复制代码

_proto_

所有对象在创建时都会带有 __proto__ 的隐式原型属性,用于指向构造他的函数的 prototype

function Person() {}
Person.prototype.name = 'xiao ming';
Person.prototype.age  = 18;

var xiaoming = new Person();

console.log(xiaoming.__proto__ == Person.prototype); // true
复制代码

原型的继承

继承

函数在 prototype 上定义的的属性可以被实例化后所继承

function Person() {}
Person.prototype.name = 'xiao ming';
Person.prototype.age  = 18;

var xiaoming = new Person();
console.log(xiaoming.name); // xiao ming
console.log(xiaoming.age); // 18
console.log(xiaoming instanceof Person); // true
复制代码

原型查找顺序

在实例访问某个属性时,如果自身没有,则会依次向上查找直到 找到/找不到 ,例子和图示如下

function Person() {}
Person.prototype.name = 'xiao ming';
Person.prototype.age  = 18;

var xiaoming = new Person();
xiaoming.name = 'xiao dong';
console.log(xiaoming.name); // xiao dong

delete xiaoming.name;
console.log(xiaoming.name); // xiao ming
复制代码

函数间继承

经过上面例子,我们可以知道所谓继承,其实就是原型上的查找,那么函数之间要如何继承是不是就不难理解了?

function People() {
    this.type = 'human';
}

function Person() {
    this.name = 'xiao ming';
    this.age = 18;
}

Person.prototype = new People();
// 修复 constructor 指向
Person.prototype.constructor = Person;

var xiaoming = new Person();
console.log(xiaoming.name); // xiao ming
console.log(xiaoming.type); // human
复制代码

继承的问题

不同的实例可以继承相同的原型,但是要注意,原型上的引用在不同实例中是会共享的

function Person() {}
Person.prototype.name = 'xiao ming';
Person.prototype.age  = 18;
Person.prototype.friends = ['xiao mei', 'xiao li'];

var xiaoming = new Person();
var xiaodong = new Person();

xiaoming.friends.push('xiao hong');

console.log(xiaoming.friends == xiaodong.friends); // true
console.log(xiaoming.friends); // ["xiao mei", "xiao li", "xiao hong"]
console.log(xiaodong.friends); // ["xiao mei", "xiao li", "xiao hong"]
复制代码

原型链

通过 __proto__ 属性连接所有原型,这个链状关系称为 原型链
根据文章的例子,我可以从下面的图去观察原型链

image.png

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享