前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【深入理解JS核心技术】2. 什么是原型链?

【深入理解JS核心技术】2. 什么是原型链?

作者头像
达达前端
发布2022-05-11 21:18:13
3150
发布2022-05-11 21:18:13
举报
文章被收录于专栏:达达前端达达前端

原型链是用于在现有对象的基础上构建新类型的对象。它类似于基于类的语言中的继承。

对象实例的原型可以通过 Obeject.getPrototypeOf(object) 或 proto 属性获得,而构造函数的原型可通过 Object.prototype 获得。

构造函数,原型,实例的关系:

每个构造函数都有一个原型对象,原型有一个属性指回构造函数,而实例有一个内部指针指向原型。

原型链的基本思想:(如果原型是另一个类型的实例?)原型当成实例。

意味着这个原型本身有一个内部指针指向另一个原型,相应地另一个原型也有一个指针指向另一个构造函数。这样就在实例和原型之间构造了一条原型链。

代码语言:javascript
复制
function SuperType() {
 this.property = true;
}

SuperType.prototype.getSuperValue = function() {
 return this.property;
};

function SubType() {
 this.subproperty = false;
}

// 继承SuperType
SubType.prototype = new SuperType();

SubType.prototype.getSubValue = function() {
 return this.subproperty;
};

let instance = new SubType();
console.log(instance.getSuperValue()); // true
复制代码
  1. 默认原型

默认情况下,所有引用类型都继承自Object,这也是通过原型链实现的。任何函数的默认原型都是一个Object的实例,这意味着这个实例有一个内部指针指向Object.prototype。

2. 原型与继承关系

原型与实例的关系可以通过两种方式来确定。第一种方式是使用instanceof操作符,如果一个实例的原型链中出现过相应的构造函数,则instanceof返回true。

确定关系的第二种方式是使用 isPrototypeOf() 方法。原型链中的每个原型都可以调用这个方法。

代码语言:javascript
复制
// 只要原型链中包含这个原型,这个方法就返回true
console.log(Object.prototype.isPrototypeOf(instance)); // true
复制代码

3. 关于方法

子类有时候需要覆盖父类的方法,或者增加父类没有的方法。这些方法必须在原型赋值之后再添加到原型上。

代码语言:javascript
复制
function SuperType() {
 this.property = true;
}

SuperType.prototype.getSuperValue = function() {
 return this.property;
}

function SubType() {
 this.subproperty = false;
}

// 继承SuperType
SubType.prototype = new SuperType();

// 新方法
SubType.prototype.getSubValue = function() {
 return this.subproperty;
};

// 覆盖已有的方法
SubType.prototype.getSuperValue = function() {
 return false;
};

let instance = new SubType();
console.log(instance.getSuperValue()); // false
复制代码

重点:如果以对象字面量方式创建原型方法会破坏之前的原型链,因为这相当于重写了原型链。

代码语言:javascript
复制
function SuperType() {
 this.property = true;
}

SuperType.prototype.getSuperValue = function() {
 return this.property;
};

function SubType() {
 this.subproperty = false;
};

// 继承SuperType
SubType.prototype = new SuperType();

// 通过对象字面量添加新方法,这会导致上一行无效
SubType.prototype = {
 getSubValue() {
  return this.subproperty;
 },
 someOtherMethod() {
  return false;
 }
};

let instance = new SubType();
console.log(instance.getSuperValue()); // 出错
复制代码
  1. 原型链的问题

原型中包含的引用值会在所有实例间共享,这也是为什么属性通常会在构造函数中定义而不会在原型上的原因。

在使用原型实现继承时,原型实际上变成了另一个类型的实例。(原先的实例属性变成了原型属性)

代码语言:javascript
复制
function SuperType() {
 this.colors = ["red", "blue", "green"];
}

function SubType() { }

// 继承SuperType
SubType.prototype = new SuperType();

let instance1 = new SubType();
instance1.colors.push('black');
console.log(instance1.colors); // "red,blue,green,black"

let instance2 = new SubType();
console.log(instance2.colors); // "red,blue,green,black"
复制代码

原型链的第二个问题:子类型在实例化时不能给父类型的构造函数传参。

未完结!更多内容尽情期待下一节~

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-05-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档