原型链的理解

栏目: JavaScript · 发布时间: 5年前

内容简介:此贴用于记录原型链相关的一些东西。函数都有prototype,对象都有__proto__,一个函数的prototype和一个对象的__proto__就是原型,原型其实也是一个对象。一个函数的prototype和这个函数的示例对象的__proto__是同一个引用,即:

此贴用于记录原型链相关的一些东西。

函数都有prototype,对象都有__proto__,一个函数的prototype和一个对象的__proto__就是原型,原型其实也是一个对象。

一个函数的prototype和这个函数的示例对象的__proto__是同一个引用,即:

function A(){
}

let a = new A();
console.log(a.__proto__ === A.prototype); //返回的是true

当调用某一个对象的方法的时候,如果找不到这个对象的方法,则会去找这个对象的原型里的方法,如果再找不到,则继续找原型的原型的方法,一直往上找,这个就是原型链,如果都找不到,则会报错。

在引入es6的extends之前,函数的继承就是通过原型来实现的。下面记录一下我理解的继承,下面的继承参考的是[JS继承的实现方式

][1],他那里有完整的继承方法。

一. 原型链继承

function A(name) {
  this.name = name;
  this.f1 = function () {
    console.log(this.name + '正在做f1');
  }
}
A.prototype.f2 = function () {
  console.log(this.name + '正在做f2');
}

function B(name) {
  this.name = name;
}

B.prototype = new A('');

let b = new B('test');
b.f1();
b.f2();
console.log(b.__proto__ === B.prototype); //true

console.log(b instanceof A);//true
console.log(b instanceof B);//true

优点:

1.简单,实现容易

2.能访问父类所有的方法和属性

3.实例是当前类的实例,也是父类的实例

缺点:

1.要给B的prototype新增方法必须要在 new A('');之后

2.无法实现多继承

3.没法向父类的构造函数传递参数

二. 构造继承

function A(name){
  this.name = name;
  this.f1 = function(){
    console.log(this.name + '正在做f1');
  }
}
A.prototype.f2 = function(){
  console.log(this.name + '正在做f2');
}

function B(name) {
  A.call(this, name);
}

let b = new B('test');
b.f1();
// b.f2();// 会报错

console.log(b instanceof A);//false
console.log(b instanceof B);//true

优点:

1.可以使用父类的属性和方法

2.可以实现多重继承,即可以call多个函数

3.实例对象是当前类的实例,不是父类的实例

缺点:

1.无法获取A的prototype的属性和方法

2.只是子类的实例,不是父类的实例

3.无法实现函数复用,每个子类都有父类实例函数的副本,影响性能(此处应该是调用call的时候会生成父类的实例副本,具体的还得再研究研究)

三. 组合继承

function A(name){
  this.name = name;
  this.f1 = function(){
    console.log(this.name + '正在做f1');
  }
}
A.prototype.f2 = function(){
  console.log(this.name + '正在做f2');
}

function B(name) {
  A.call(this, name);
}
B.prototype = new A('');
//要修正prototype的constructor,为什么要修正还有待研究
B.prototype.constructor = B;

let b = new B('test');
b.f1();
b.f2();

console.log(b instanceof A);//true
console.log(b instanceof B);//true

优点:

1.包含了原型链继承和构造继承的优点

2.解决了原型链继承的无法实现多继承和没法向父类的构造函数传递参数的缺点

3.解决了构造继承无法获取A的prototype的属性和方法还有只是子类的实例,不是父类的实例的问题

缺点:

1.调用了两次父类构造函数,生成了两份实例(子类实例将子类原型上的那份屏蔽了)

四.寄生组合继承

function A(name){
  this.name = name;
  this.f1 = function(){
    console.log(this.name + '正在做f1');
  }
}
A.prototype.f2 = function(){
  console.log(this.name + '正在做f2');
}

function B(name) {
  A.call(this, name);
}

(function(){
  // 创建一个没有实例方法的类
  var Super = function(){};
  Super.prototype = A.prototype;
  //将实例作为子类的原型,这样就可以只获取A的prototype的属性了
  B.prototype = new Super();
  //
  B.prototype.constructor = B;
})();

let b = new B('test');
b.f1();
b.f2();

console.log(b instanceof A);//true
console.log(b instanceof B);//true

优点:

1.在组合继承的基础上,只生成了一份父类的实例,prototype也只继承了父类的prototype,没有继承私有的属性

缺点:

1.实现复杂


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

ES6 标准入门(第2版)

ES6 标准入门(第2版)

阮一峰 / 电子工业出版社 / 2016-1 / 69.00元

ES6(又名 ES2105)是 JavaScript 语言的新标准,2015 年 6 月正式发布后,得到了迅速推广,是目前业界超级活跃的计算机语言。《ES6标准入门(第2版)》是国内仅有的一本 ES6 教程,在前版基础上增补了大量内容——对标准进行了彻底的解读,所有新增的语法知识(包括即将发布的 ES7)都给予了详细介绍,并且紧扣业界开发实践,给出了大量简洁易懂、可以即学即用的示例代码。 《......一起来看看 《ES6 标准入门(第2版)》 这本书的介绍吧!

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具