iis服务器助手广告广告
返回顶部
首页 > 资讯 > 前端开发 > JavaScript >JavaScript原型链及常见的继承方法
  • 903
分享到

JavaScript原型链及常见的继承方法

2024-04-02 19:04:59 903人浏览 独家记忆
摘要

目录原型链原型链的概念原型链的问题几种常见的继承方法盗用构造函数组合继承原型式继承寄生式继承寄生组合式继承原型链 原型链的概念 在javascript中,每一个构造函数都有一个原型,

原型链

原型链的概念

javascript中,每一个构造函数都有一个原型,这个原型中有一个属性constructor会再次指回这个构造函数,这个构造函数所创造的实例对象,会有一个指针(也就是我们说的隐式原型__proto__或者是浏览器中显示的[[Prototype]])指向这个构造函数的原型对象。如果说该构造函数的原型对象也是由另外一个构造函数所创造的实例,那么该构造函数的原型对象也会存在一个指针指向另外一个构造函数的原型对象,周而复始,就形成了一条原型链。 最特别的是所有的没有经过再继承函数都是由Function实例化来的,所有的除了函数外的对象都是由Object实例化来的,其中Object也是由Function实例化来的,但是Object.prototype.__proto__ === null 是成立的。

再强调一遍:原型链是沿着对象的隐式原型一层层的去寻找的,找到的是构造函数所创造的实例。例如下:

这个就是相当于由Studentnew 出来的实例s,查找自身的 name 属性,然后沿着原型链查找,找到Student中的prototype当中,然后找到了name这个属性。

而这个例子,由红框框起来的代码(寄生继承的关键代码),代替注释掉的部分,最终s是找不到name属性的,这是因为红框中的代码,仅仅是将Student的隐式原型指向了Person的显示原型对象,未能创建任何的实例,当然就不会存在属性这个说法。

原型链的问题

原型链的问题主要有两个方面,第一个问题是,当原型中出现包含引用值(比如数组)的时候,所有在这条原型链中的实例会共享这个属性,造成“一发而动全身”的问题。第二个问题就是子类在实例化时,不能够给父类型的构造函数传参,即

无法在不影响所有对象实例的情况下把参数传递进父类型的构造函数传参

几种常见的继承方法

盗用构造函数

function SuperType() {
    this.friends = ['张三','李四']
}

function SubType() {
    SuperType.call(this);
}

const p1 = new SubType();
p1.friends.push('王武');

const p2 = new SubType();
console.log(p2.friends); // ['张三','李四', '王武']

盗用构造函数实现继承在这个例子中有了充分的体现: 首先在子类的构造函数中调用父类的构造函数。因为毕竟函数就是特定上下文中执行代码的简单对象,所以可以使用call()方法以创建的对象为上下文执行的构造函数。

盗用构造函数的主要问题,也是创建对象的几种方式中构造函数模式自定义类型的问题:必须在构造函数中定义方法,造成内存浪费。另外,子类也不能访问父类原型上定义的方法,因此,盗用构造函数也不会单独使用。

组合继承

组合继承也称为伪经典继承,综合了原型链和构造函数,将两者的有点结合起来。基本的思路就是使用原型链继承原型上的属性和方法,而通过盗用构造函数继承实现实例的属性。这样就可以把方法定义在原型上实现复用,又可以让每个实例有自己的属性。

function SuperType(name) {
    this.name = name;
    this.friends = ['张三','李四'];
}
SuperType.prototype.sayName = function() {
    console.log(this.name)
}
// 继承方法
SubType.prototype = new SuperType();
function SubType(name, age) {
    SuperType.call(this, name);
    this.age = age;
}
const p1 = new SubType('赵六', 12);
const p2 = new SubType('赵六2', 22);
// 创建的 p1 和 p2 能够拥有自己的属性并且引用值属性也是独立的,此外,每一个实例能够公用父类的方法。

组合继承已经接近完美了,但是,我们发现,实现组合继承就要调用两次父类构造函数。在本质上,子类型最终是要包含超类对象的所有实例属性,子类构造函数只要在执行时重写自己的原型就行了,这就为减少一次调用父类构造函数提供了思路。

原型式继承

const person = {
    name: 'zs',
    friends: ['ls','ww']
}
// 创造出一个实例,这个实例的隐式原型指向 person
const anotherPerosn = Object.create(person);
anotherPerosn.name = 'xm'
anotherPerosn.friends.push('zl')

console.log(anotherPerosn.name) // xm
console.log(anotherPerosn.friends) // ['ls','ww', 'zl'];

const anotherPerosn2 = Object.create(person);
anotherPerosn.name = 'xh'
anotherPerosn.friends.push('dd')

console.log(anotherPerosn2.name) // xh
console.log(anotherPerosn2.friends) // ['ls','ww', 'zl', 'dd'];

对于原型链继承就不再过多的解释了。。。。

寄生式继承

寄生式继承与原型式继承比较相似,都会存在属性引用值共享的问题。

function createAnotherPerson(original) {
    const clone = Object.create(original); //通过调用函数创建一个新的对象
    clone.sayHi = function() { // 以某种方式增强这个对象
        console.log('Hi');
    }
    return clone;
}

寄生式继承,不仅存在着属性引用值共享的问题而且函数还不能进行复用。

寄生组合式继承

// 实现了寄生式组合继承的核心逻辑
function inheritPrototype(subFn, parentFn){
    subFn.prototype = Object.create(parentFn.prototype); // 创建赋值对象
    Object.defineProperty(subFn.prototype,'constructor', {   // 增强对象
        enumerable: false,
        writable: false,
        configurable: false,
        value: subFn,
    })
}
function Person(name, age, address) {
    this.name = name;
    this.age = age;
    this.address = address;
}
Person.prototype.eating = function() {
        console.log(this.name + "正在吃饭");
} // 共享方法

function Student(name, age, address, sno) {
    Person.call(this, name, age, address); // 绑定 this 确保创建出来的对象是相互独立的
    this.sno = sno;
    this.studing = function() {
        console.log(`${this.name}正在学习`)
    }
}

function Teacher(name, age, address, tno) {
    Person.call(this, name, age, address)
    this.tno = tno;
}

寄生+组合式(构造函数+原型链)完美的解决了其他继承出现的问题。

到此这篇关于JavaScript原型链及常见的继承方法的文章就介绍到这了,更多相关js原型链内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: JavaScript原型链及常见的继承方法

本文链接: https://www.lsjlt.com/news/164905.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • JavaScript原型链及常见的继承方法
    目录原型链原型链的概念原型链的问题几种常见的继承方法盗用构造函数组合继承原型式继承寄生式继承寄生组合式继承原型链 原型链的概念 在JavaScript中,每一个构造函数都有一个原型,...
    99+
    2022-11-13
  • javascript原型链继承的使用方法
    这篇文章主要讲解了“javascript原型链继承的使用方法”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“javascript原型链继承的使用方法”吧!说明即使不自定义类型,也可以通过原型实...
    99+
    2023-06-20
  • JavaScript原型链继承的概念以及原理分享
    本篇文章和大家了解一下JavaScript原型链继承的概念以及原理分享。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。一、原型链所谓原型链就是指通过原型链继承,在原型之间建立起来的链式结构被称为原型链。当查找对象的某个属性...
    99+
    2023-06-14
  • JavaScript的继承和原型链是什么
    小编给大家分享一下JavaScript的继承和原型链是什么,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!一、前言JavaScri...
    99+
    2022-10-19
  • JavaScript中常见的七种继承及实现
    目录1. 原型链继承2. 借用构造函数继承3. 组合继承4. 原型式继承5. 寄生式继承6. 寄生式组合继承7. class继承1. 原型链继承 原型链继承是 JavaScript ...
    99+
    2023-03-08
    JavaScript实现继承方式 JavaScript继承
  • JavaScript中常见的几种继承方式
    目录原型继承内存图分析盗用构造函数继承分析组合继承原型链继承寄生式继承寄生组合式继承原型继承 function Parent(name) { this.name = name }...
    99+
    2022-11-13
  • JavaScript的原型及原型链的用法
    这篇文章给大家介绍JavaScript的原型及原型链的用法,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。JavaScript 是世界上最流行的脚本语言。 JavaScript 是属于 web 的语言,它适用于 PC、笔...
    99+
    2023-06-02
  • 一文详解如何用原型链的方式实现JS继承
    目录原型链是什么通过构造函数创建实例对象用原型链的方式实现继承方法1:Object.create方法2:直接修改 [[prototype]]方法3:使用父类的实例总结今天讲一道经典的...
    99+
    2022-11-13
  • JavaScript面向对象编程中的原型继承实例用法
    这篇文章主要介绍“JavaScript面向对象编程中的原型继承实例用法”,在日常操作中,相信很多人在JavaScript面向对象编程中的原型继承实例用法问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操...
    99+
    2022-10-19
  • 常见的JavaScript内存错误及解决方法
    目录1.计时器的监听2.事件监听3.Observers4. Window Object5. 持有DOM引用前言: JavaScript 不提供任何内存管理操作。相反,内存由 Java...
    99+
    2022-11-12
  • 原生JS获取URL链接参数的几种常见方法
    前言 作为一个前端开发,我们很多时候都需要对URL进行操作和处理,最常见的一种就是获取URL链接中携带的参数值了。使用框架开发的小伙伴可能会觉得这很简单,因为框架提供了很多方法让我们...
    99+
    2022-11-13
  • JavaScript中常见的BUG及其修复方法分享
    这篇文章主要讲解了“JavaScript中常见的BUG及其修复方法分享”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“JavaScript中常见的BUG及其修复方法分享”吧!如今网站几乎100...
    99+
    2023-06-04
  • Oracle常见死锁发生的原因以及解决方法
    一.删除和更新之间引起的死锁 造成死锁的原因就是多个线程或进程对同一个资源的争抢或相互依赖。这里列举一个对同一个资源的争抢造成死锁的实例。 CREATE ...
    99+
    2022-10-18
  • 一些常见IIS无法访问PHP的原因及解决方法
    在Windows的Web服务器环境中,IIS是非常常见的Web服务器软件之一。作为一个全面的Web服务器,IIS可以运行各种类型的Web应用程序,包括基于PHP语言编写的应用程序。然而,在实际应用中,有时我们会发现IIS无法访问或运行PHP...
    99+
    2023-05-14
    php iis
  • 常见IIS无法访问PHP的原因及解决方法是什么
    这篇文章主要讲解了“常见IIS无法访问PHP的原因及解决方法是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“常见IIS无法访问PHP的原因及解决方法是什么”吧!错误的PHP设置如果你的I...
    99+
    2023-07-05
  • C++中常见的数据类型转换问题及解决方法
    C++ 中常见的数据类型转换问题及解决方法引言:在 C++ 编程中,经常会遇到不同数据类型之间的转换问题。正确地进行数据类型转换是保证程序正确性和性能的关键之一。本文将介绍一些常见的数据类型转换问题,并提供相应的解决方法和具体的代码示例。一...
    99+
    2023-10-22
    解决方法 数据类型转换 C++问题
  • Win7系统常见的3种自动关机原因及解决方法
    相信不少出现这些问题也是一件不那么美好的事情,我们将Windows7旗舰版下载 使用后我们会发现其实有不少系统自动关机的情况都是类似的,因此我们也可以从下面几个原因来简单分析一下系统自动关机的故障。 NO.1 病毒导致 ...
    99+
    2023-06-13
    Win7系统 常见自动关机原因 原因 系统 解决 自动关机 Win7
  • Win7常见启动故障产生的原因及解决方法整理
      相信绝大多数朋友都用上了Win7系统了吧,Win7系统虽然比以前其他版本的Windows系统都稳定得多,但是由于安装某些特殊软件或误操作,系统还是会出现各种启动故障。接下来,笔者就来给大家分析一下Win7常见启动故障...
    99+
    2023-06-02
    win7 启动故障 解决 原因 故障 整理 方法
  • GO编程中常见的数据类型错误及其解决方法
    在GO编程中,数据类型错误常常是程序出现问题的主要原因之一。本文将介绍GO编程中常见的数据类型错误,并提供相应的解决方法。 类型不匹配 类型不匹配是GO编程中最常见的类型错误之一。它通常发生在将一个类型的值赋给另一个类型时。 例如,下...
    99+
    2023-09-20
    关键字 数据类型 编程算法
  • 【总结】PHP服务器报错的常见类型及其解决方法
    PHP 是当今网络应用开发中最常用的编程语言之一,也是一个运行在服务器端的语言。在开发过程中,由于各种原因,PHP 服务器可能会经常出现各种报错信息。这篇文章将介绍 PHP 服务器报错的常见类型及其解决方法。Syntax Error语法错误...
    99+
    2023-05-14
    php
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作