原型链的理解

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

内容简介:此贴用于记录原型链相关的一些东西。函数都有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.实现复杂


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

查看所有标签

猜你喜欢:

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

区块链革命

区块链革命

[加]唐塔普斯科特(Don Tapscott)、[加]亚力克斯·塔普斯科特(Alex Tapscott) / 中信出版集团股份有限公司 / 2016-9 / 69

(1)国际大腕“数字经济之父”继畅销书《维基经济学》之后再出力作! (2)一本真正全景式描述区块链理论及应用的巨著! (3)苹果共同创始人史蒂夫·沃兹尼亚克、世界经济论坛创始人和论坛主席克劳斯·施瓦布、网景及硅谷安德森·霍洛维茨风险投资公司创始人马克·安德森、麦肯锡董事长兼全球总裁鲍达民、 百事公司首席执行官卢英德、丹·舒尔曼 Paypal公司首席执行官等全球政治界、学术界和商界精英联......一起来看看 《区块链革命》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

随机密码生成器
随机密码生成器

多种字符组合密码

html转js在线工具
html转js在线工具

html转js在线工具