前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >《现代Javascript高级教程》JavaScript中的原型与继承

《现代Javascript高级教程》JavaScript中的原型与继承

作者头像
linwu
发布于 2023-07-27 07:13:57
发布于 2023-07-27 07:13:57
29200
代码可运行
举报
文章被收录于专栏:编程时光编程时光
运行总次数:0
代码可运行

现代JavaScript高级小册

深入浅出Dart

现代TypeScript高级小册

原型和原型链

JavaScript是一门支持面向对象编程的语言,它的函数是第一公民,同时也拥有类的概念。不同于传统的基于类的继承,JavaScript的类和继承是基于原型链模型的。在ES2015/ES6中引入了class关键字,但其本质仍然是基于原型链的语法糖。

原型(Prototype)

原型(Prototype)是JavaScript中对象的一个特殊属性,它用于实现属性和方法的继承。在JavaScript中,每个对象都有一个原型属性,它指向另一个对象,这个对象被称为原型对象。通过原型链,对象可以从原型对象继承属性和方法。

原型的概念可以用以下方式解释:每个JavaScript对象都是基于一个构造函数创建的,构造函数是对象的模板或蓝图。在创建对象时,构造函数会创建一个关联的原型对象,对象通过原型链继承原型对象上的属性和方法。原型对象是一个普通的JavaScript对象,它具有自己的属性和方法。

让我们以一个示例来说明原型的概念和作用:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 构造函数
function Person(name) {
  this.name = name;
}

// 在原型对象上添加方法
Person.prototype.sayHello = function() {
  console.log("Hello, my name is " + this.name);
};

// 创建实例
var person1 = new Person("John");
var person2 = new Person("Alice");

// 调用原型对象上的方法
person1.sayHello(); // 输出: "Hello, my name is John"
person2.sayHello(); // 输出: "Hello, my name is Alice"

在这个示例中,我们定义了一个构造函数Person,它有一个name属性。然后,我们通过给原型对象Person.prototype添加一个sayHello方法,使得所有通过Person构造函数创建的实例都可以访问该方法。我们创建了两个实例person1person2,并分别调用了sayHello方法。

原型的重要性体现在以下几个方面:

  1. 继承:原型链允许对象继承其原型对象上的属性和方法。通过原型链,子对象可以访问和复用父对象的属性和方法,实现了继承的概念。
  2. 代码复用和共享:通过将方法和属性定义在原型对象上,可以实现多个对象共享相同的方法和属性。这样可以节省内存空间,提高性能,同时也方便了代码的维护和扩展。

下面是一个简单的原型链示意图:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
           +----------------------+
           |     Object.prototype |
           +----------------------+
                      ^
                      |
           +----------------------+
           |    Constructor.prototype |
           +----------------------+
                      ^
                      |
           +----------------------+
           |       Object instance |
           +----------------------+

在这个示意图中,Object.prototype是所有对象的原型,Constructor.prototype是构造函数的原型,Object instance是基于构造函数创建的对象实例。

构造函数和原型对象

构造函数是用于创建对象的特殊函数。它通常以大写字母开头,通过使用 new 关键字来调用构造函数,我们可以创建一个新的对象实例。构造函数在创建对象时可以执行一些初始化操作,并为对象添加属性和方法。

原型对象是构造函数的一个属性,它是一个普通的 JavaScript 对象。原型对象上的属性和方法可以被通过构造函数创建的对象实例所继承。通过将属性和方法定义在原型对象上,我们可以实现方法的共享和节省内存空间。

让我们通过一个示例来说明构造函数和原型对象的概念以及如何使用它们来创建对象和共享方法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 构造函数
function Person(name, age) {
  this.name = name;
  this.age = age;
}

// 在原型对象上添加方法
Person.prototype.sayHello = function() {
  console.log("Hello, my name is " + this.name + " and I am " + this.age + " years old.");
};

// 创建对象实例
var person1 = new Person("John", 25);
var person2 = new Person("Alice", 30);

// 调用共享的方法
person1.sayHello(); // 输出: "Hello, my name is John and I am 25 years old."
person2.sayHello(); // 输出: "Hello, my name is Alice and I am 30 years old."

在这个示例中,我们定义了一个构造函数 Person,它接受 nameage 参数,并将它们赋值给对象的属性。然后,我们通过在原型对象 Person.prototype 上添加一个方法 sayHello,使得通过 Person 构造函数创建的对象实例可以访问该方法。我们创建了两个对象实例 person1person2,并分别调用了共享的方法 sayHello

以下是一个简单的构造函数和原型对象的流程图示意图:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
+----------------------------------+
|           Constructor            |
|                                  |
|  +--------------------------+    |
|  |   Prototype Properties   |    |
|  +--------------------------+    |
|                                  |
|  - Property: name               |
|  - Property: age                |
|  - Method: sayHello()           |
|                                  |
+----------------------------------+
        ^
        |
        |
+----------------------------------+
|          Object Instance         |
|                                  |
|  +--------------------------+    |
|  |     Instance Properties   |    |
|  +--------------------------+    |
|                                  |
|  - Property: name               |
|  - Property: age                |
|                                  |
+----------------------------------+

在这个示意图中,构造函数和原型对象之间存在关联,构造函数拥有原型对象的引用。通过构造函数,我们可以创建对象实例,并且这些实例可以通过原型对象继承原型上的属性和方法。

原型链

原型链是 JavaScript 中对象之间通过原型链接起来的机制,用于实现属性和方法的继承。它是由一系列的原型对象组成,每个对象都有一个指向其原型对象的连接,形成了一条链式结构。

原型链的概念可以通过以下方式解释:在 JavaScript 中,每个对象都有一个内部属性 [[Prototype]](__proto__),它指向该对象的原型。当我们访问一个对象的属性或方法时,如果该对象本身没有这个属性或方法,JavaScript 引擎会自动沿着原型链向上查找,直到找到匹配的属性或方法或者到达原型链的顶部(Object.prototype)。

让我们通过一个示例来说明原型链的概念和工作原理:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 父对象构造函数
function Parent() {
  this.name = "Parent";
}

// 在父对象原型上添加方法
Parent.prototype.sayHello = function() {
  console.log("Hello, I am " + this.name);
};

// 子对象构造函数
function Child() {
  this.name = "Child";
}

// 通过原型继承建立子对象和父对象的连接
Child.prototype = Object.create(Parent.prototype);

// 创建子对象实例
var child = new Child();

// 调用父对象原型上的方法
child.sayHello(); // 输出: "Hello, I am Child"

在这个示例中,我们定义了一个父对象构造函数 Parent,它有一个属性 name 和一个原型方法 sayHello。然后,我们定义了一个子对象构造函数 Child,它也有一个属性 name。通过 Object.create() 方法,我们将子对象的原型连接到父对象的原型上,建立了子对象和父对象之间的原型链关系。最后,我们创建了子对象实例 child,并调用了父对象原型上的方法 sayHello

以下是一个简单的原型链示意图:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
           +----------------------+
           |     Object.prototype |
           +----------------------+
                      ^
                      |
           +----------------------+
           |   Parent.prototype    |
           +----------------------+
                      ^
                      |
           +----------------------+
           |   Child.prototype     |
           +----------------------+
                      ^
                      |
           +----------------------+
           |     Child instance    |
           +----------------------+

在这个示意图中,Object.prototype 是所有对象的顶层原型,Parent.prototype 是父对象的原型,Child.prototype 是子对象的原型,Child instance 是基于子对象构造函数创建的对象实例。

原型链的重要性体现在以下几个方面:

  1. 继承:原型链允许对象通过继承获取其他对象的属性和方法。子对象可以继承父对象的属性和方法,而父对象又可以继承更上层对象的属性和方法,以此类推。
  2. 代码复用和共享:通过原型链,我们可以在原型对象

上定义方法和属性,从而实现多个对象之间的方法共享和代码复用。这样可以节省内存空间,提高性能,并减少代码的冗余。

  1. 扩展和修改:通过在原型对象上添加新的方法和属性,我们可以在整个原型链中的所有对象实例上访问和使用这些扩展。这样可以方便地对现有对象进行功能扩展和修改。

原型继承

原型继承是一种通过继承原型对象来创建新对象的方式。在 JavaScript 中,我们可以使用多种方式实现原型继承。原型继承的概念是通过将一个对象作为另一个对象的原型来实现继承,从而使新对象可以共享原型对象的属性和方法。

1. 对象字面量和 Object.create():可以使用字面量对象定义属性和方法,并使用 Object.create() 方法创建一个新对象,并将其原型设置为现有对象的原型。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var parent = {
  name: "Parent",
  sayHello: function() {
    console.log("Hello, I am " + this.name);
  }
};

var child = Object.create(parent);
child.name = "Child";

2. 构造函数和 Object.create():可以使用构造函数定义对象,并通过 Object.create() 方法将新对象的原型连接到现有对象的原型上。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function Parent(name) {
  this.name = name;
}

Parent.prototype.sayHello = function() {
  console.log("Hello, I am " + this.name);
};

function Child(name) {
  Parent.call(this, name);
}

Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;

var child = new Child("Child");

3. 构造函数和 new 关键字:可以使用构造函数创建对象实例,并使用 new 关键字进行实例化。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function Parent(name) {
  this.name = name;
}

Parent.prototype.sayHello = function() {
  console.log("Hello, I am " + this.name);
};

function Child(name) {
  Parent.call(this, name);
}

Child.prototype = new Parent();
Child.prototype.constructor = Child;

var child = new Child("Child");

4. 寄生组合继承

寄生组合继承是一种常用的原型继承方式,结合了构造函数继承和原型链继承的优点,避免了原型链中不必要的属性复制和方法重复定义的问题。这种方式先通过构造函数继承属性,然后通过设置原型链继承方法。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function Parent(name) {
  this.name = name;
}

Parent.prototype.sayHello = function() {
  console.log("Hello, I am " + this.name);
};

function Child(name, age) {
  Parent.call(this, name);
  this.age = age;
}

Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;

var child = new Child("Child", 10);

以上是常用的原型继承实现方式,每种方式都有其特点和适用场景。根据具体的需求和代码结构,可以选择最适合的方式来实现原型继承。

参考资料

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

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

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

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

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Javascript继承,再谈
     说到Javascript的继承,相信只要是前端开发者都有所了解或应用,因为这是太基础的知识了。但不知各位有没有深入去理解其中的玄机与奥秘。今本人不才,但也想用自己的理解来说一说这其中的玄机和奥秘。 一、类继承的发展吏 function实现的继承 function的继承是完全模仿了OOP的编程思想。实现的是类的继承 object.create实现的继承 用object.create来修改其原型 es6的继承 增加了class来模拟OOP的继承实现。上述两种继承实现,他都还是支持的。
sam dragon
2018/03/28
8260
JavaScript的几种继承方式
这篇文章称为笔记更为合适一些,内容来源于 《JavaScript高级程序设计 (第三版)》第六章 6.3 继承。
木子星兮
2020/07/16
5430
JavaScript实现继承
使用class继承非常简单。子类使用extends关键字表明继承于哪个类,并在子类中调用super(),这相当于使用call()改变this的指向。
不作声
2020/10/30
4220
JS中的面向对象、原型、原型链、继承总结大全
补充: js中说一切都是对象,是不完全的,在js中6种数据类型(Undefined,Null,Number,Boolean,String,Object)中,前五种是基本数据类型,是原始值类型,这些值是在底层实现的,他们不是object,所以没有原型,没有构造函数,所以并不是像创建对象那样通过构造函数创建的实例。关于对象属性类型的介绍就不介绍了。
疯狂的技术宅
2019/03/27
1.5K0
JS中的面向对象、原型、原型链、继承总结大全
JavaScript 面向对象继承详解
由于js不像java那样是完全面向对象的语言,js是基于对象的,它没有类的概念。所以,要想实现继承,一般都是基于原型链的方式;
书童小二
2018/09/03
5270
JavaScript 面向对象继承详解
JavaScript两种继承方式详解
由于js不像java那样是真正面向对象的语言,js是基于对象的,它没有类的概念。所以,要想实现继承,可以用js的原型prototype机制或者用apply和call方法去实现
疯狂的技术宅
2019/03/27
7100
深入理解javascript中的继承机制 之 12种继承模式总结原型链法仅从原型继承临时构造器原型属性拷贝所有属性拷贝(浅拷贝)深拷贝原型继承法扩展与增强模式多重继承法寄生式继承借用构造函数:构造器于
之前我们介绍了多种javascript中的继承方式,最后我们开始总结概括这些继承方式,先将javascript中的继承分类,根据不同的条件,可以分成不同的类别。 最常用的我们可以分为这两类:
desperate633
2018/08/22
5060
Javascript的原型继承,说清楚
     一直以来对Javascript的原型、原型链、继承等东西都只是会用和了解,但没有深入去理解这门语言关于继承这方面的本质和特点。闲暇之余做的理解和总结,欢迎各位朋友一起讨论。 本文本主要从两段代码的区别说明继承: 一、第一段代码: function Parent(){ this.Name='parent'; } Parent.prototype.getName = function(){ return this.Name; } Parent.prototype.Share = [
sam dragon
2018/01/17
5590
Javascript的原型继承,说清楚
「思维导图学前端 」一文搞懂Javascript对象,原型,继承
去年开始我给自己画了一张知识体系的思维导图,用于规划自己的学习范围和方向。但是我犯了一个大错,我的思维导图只是一个全局的蓝图,而在学习某个知识点的时候没有系统化,知识太过于零散,另一方面也很容易遗忘,回头复习时没有一个提纲,整体的学习效率不高。意识到这一点,我最近开始用思维导图去学习和总结具体的知识点,效果还不错。试想一下,一张思维导图的某个端点是另一张思维导图,这样串起来的知识链条是多么“酸爽”!当然,YY一下就好了,我保证你没有足够的时间给所有知识点都画上思维导图,挑重点即可。
程序员白彬
2020/07/10
7910
「思维导图学前端 」一文搞懂Javascript对象,原型,继承
JavaScript中6种继承方式总结
我们在代码里的操作本意是只改变goku1的属性,但是为什么goku2的属性也被改变了呢?因为skill是一个数组,为引用类型,goku1与goku2的skill实际是指向同一块内存空间,因此修改会变得混乱。我们将在接下来的继承方式中解决这个问题。
henu_Newxc03
2022/05/05
3910
JavaScript中6种继承方式总结
Javascript 的继承总结
写惯了 TypeScript 的人很容易了解继承(extends),比如类的继承和接口的继承等,传送门:www.tslang.cn/docs/handbo… ,但是对于ES2015出现之前,JavaScript如何实现继承的呢?毫无疑问,只能通过原型链的方式实现继承,本篇主要是在读书时遇到了原型继承的问题,回顾以下原型继承的集中方式并整理成笔记方便日后查阅。
Meteors
2021/12/08
2860
【JS 构造|原型|原型链|继承(圣杯模式)|ES6类语法】下篇
❗️ ❗️ ❗️本篇系将带来JavaScript中的构造——原型——原型链——继承——ES6类语法系列知识完整讲解。 ❗️ ❗️ ❗️ ❕上篇涉及:构造——原型——原型链 ❕下篇涉及:继承——ES6类语法
好吃懒洋洋
2022/11/21
8080
【JS 构造|原型|原型链|继承(圣杯模式)|ES6类语法】下篇
OOP in Javascript
写了几篇Vue入门的内容了,今天写点其它的放松一下,简单讲讲javascript中的面相对象。 在面向对象的语言中,都有类的概念,当然es6中开始javascript中也有类的概念了,这里以es5为基础开始讲解,毕竟当前即使写的es6代码,一般还是会通过babel等转码器翻译到es5来执行的; 在js中虽然没有类的概念,但是我们却可以创建对象,一般创建对象有两种方式(这里指自定义对象): 1、使用构造函数 function Person(){ } var p=new Person(); 2、使用字面量
Jerremy
2018/06/13
5100
一篇文章告诉你JavaScript 如何实现继承
JavaScript 在编程语言界是个特殊种类,它和其他编程语言很不一样,JavaScript 可以在运行的时候动态地改变某个变量的类型。
前端皮皮
2021/11/12
2170
一篇文章告诉你JavaScript 如何实现继承
【Web前端】JavaScript 对象原型与继承机制
JavaScript 是一种动态类型的编程语言,其核心特性之一就是对象和原型链。理解原型及其工作机制对于掌握 JavaScript 的继承和对象关系非常重要。
一条晒干的咸鱼
2024/11/19
1630
【Web前端】JavaScript 对象原型与继承机制
JavaScript 中的六种继承方式
关键点:子类原型等于父类的实例Child.prototype = new Person()
Jimmy_is_jimmy
2019/07/31
5180
面向对象之继承的那几种模式
往往在项目中都会看到有用class,或者OOP思想去组织业务代码,本篇只做项目中常用到的继承以及对不同继承方式的回顾,也是再次加深对继承的一些理解,希望你在项目中有些帮助和思考。
Maic
2022/07/28
2380
面向对象之继承的那几种模式
JavaScript进阶-原型链与继承
在JavaScript中,原型链和继承是理解对象间关系和实现代码复用的核心概念。这两个机制共同构成了JavaScript面向对象编程的基础。本文将深入浅出地探讨原型链与继承的工作原理、常见问题、易错点及其避免策略,并通过具体代码示例加以说明。
Jimaks
2024/06/19
2150
JavaScript进阶-原型链与继承
JavaScript继承的实现方式:原型语言对象继承对象原理剖析
对象的继承:A 对象通过继承 B 对象,就能直接拥有 B 对象的所有属性和方法。这对于代码的复用是非常有用的。
周陆军
2021/08/14
8380
聊聊JavaScript如何实现继承
“继承”是面向对象编程里面经常提及到的概念,它的目的是实现代码复用。JavaScript并没有“类”的概念,那么,它如何实现继承呢? (ES6有关键字class和extend,继承的语法与Java等面向对象语言类似,但是,ES6 class,只是JavaScript原型继承的语法糖而已)
娜姐
2022/05/13
3380
推荐阅读
相关推荐
Javascript继承,再谈
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验