js原型与继承

94 阅读1分钟

相关定义

  • prototype: 只存在函数对象中,是对象的模板,里面的属性可以共享给对象。
  • __proto__: 是对象属性,指向创建该对象的引用类型(构造函数)的原型对象。
var one = new Person('abc', 18);
one.__proto__ = Person.prototype;
Person.prototype.__proto__ = Object.prototype;
Object.prototype.__proto__ = null;

Person.__proto__ = Function.prptotype;
Function.prototype.__proto__ = Object.protptype;
Object.prototype.__proto__ = null;

函数在创建时,就自带一个指针,指向该函数的原型对象,该原型对象有一个constructor属性,指向创建该原型对象的构造函数。即 Person.prototype.constructor = Person;

原型链

当我们读取obj.toString时,
1 看看obj本身有没有toString方法,没有则下一步。
2 看看obj.__proto__有没有toString,找到则停止查找,没有则下一步。
3 看看obj.__proto__.__proto__有没有toString,一直找到toString或者__proto__为null。

由__proto__所组成的链条,就叫原型链。

原型链继承

function Parent(props) {
    this.name = props.name;
}
Parent.prototype.introduce = function () {
    console.log('introduce', this.name)
}
function Son(props) {
    Parent.call(this, props);
    this.age = props.age;
}
function inherit(Parent, Son) {
    const F = new Function();
    F.prototype = Parent.prototype;//必须在new F之前指过去,不然后面指过去已经断了
    Son.prototype = new F();
    Son.prototype.constructor = Son;
}
inherit(Parent, Son);
Son.prototype.showAge = function () {
    console.log(this.age);
}
const son = new Son({ name: 'fcc', age: 20 });

如果在new F之前没有把F的prototype指向Parent的prototype,则new F().__proto__指向的是一个空的prototype,后面再指过去也没用了。