【JS第27期】继承-原型链

每个构造函数都有一个原型对象,原型对象都包含一个指向函数的指针,而实例都包含一个指向原型对象的内部指针。此时的原型对象将包含一个指向另一个原型的指针,相应地,另一个原型中也包含着一个指向另一个构造函数的指针,假如另一个原型又是另一个类型的实例,那么上述关系依然成立,如此层层递进,就构成了实例与原型对象的链条。也就是原型链。简单实例如下:

function Persion(name) {
  this.name = name;
}
Persion.prototype.sayName = function() {
  console.log(this.name);
}

function ChildPersion(name) {
  this.name = name;
}
// 继承了Persion
ChildPersion.prototype = new Persion();

var child = new ChildPersion('bill')
child.sayName() // bill

以上实例中,ChildPersion继承了Persion,Persion是object的实例,因此,Persion的原型都会指向一个内部指针指向object.prototype。

instanceof()

用来测试一个对象在其原型链中是否存在一个构造函数的 prototype 属性。

// 定义构造函数
function C(){} 
function D(){} 

var o = new C();


o instanceof C; // true,因为 Object.getPrototypeOf(o) === C.prototype


o instanceof D; // false,因为 D.prototype不在o的原型链上

o instanceof Object; // true,因为Object.prototype.isPrototypeOf(o)返回true
C.prototype instanceof Object // true,同上

C.prototype = {};
var o2 = new C();

o2 instanceof C; // true

o instanceof C; // false,C.prototype指向了一个空对象,这个空对象不在o的原型链上.

D.prototype = new C(); // 继承
var o3 = new D();
o3 instanceof D; // true
o3 instanceof C; // true

isPrototypeOf()

用于测试一个对象是否存在于另一个对象的原型链上。

function Foo() {}
function Bar() {}
function Baz() {}

Bar.prototype = Object.create(Foo.prototype);
Baz.prototype = Object.create(Bar.prototype);

var baz = new Baz();

console.log(Baz.prototype.isPrototypeOf(baz)); // true
console.log(Bar.prototype.isPrototypeOf(baz)); // true
console.log(Foo.prototype.isPrototypeOf(baz)); // true
console.log(Object.prototype.isPrototypeOf(baz)); // true

注意

在通过原型实现继承时,不能使用对象字面量创建原型方法,因为这样会重写原型链。如:

function Persion(name) {
  this.name = name;
}
Persion.prototype.sayName = function(){
  console.log(this.name)
}
function ChildPersion(name) {
  this.name = name;
}
ChildPersion.prototype = new Persion();
var child = new ChildPersion('bill');
child.sayName() // bill

// 重写ChildPersion.prototype
ChildPersion.prototype = {
  getName: function(){
    console.log(this.getName)
  }
}
var child2 = new ChildPersion('bill');
child2.sayName() // Uncaught TypeError: child2.sayName is not a function

原型链的问题

  • 包含引用类型的原型属性会被所有实例共享,因此,我们如果一个实例中修改了这个原型属性,那么,其他实例的对应属性也会改变
  • 在创建子类型的实例时,不能向超类型的构造函数中传递参数。
【JS第27期】继承-原型链_第1张图片
qrcode_for_gh_76cb9bd1051f_344.jpg

你可能感兴趣的:(【JS第27期】继承-原型链)