JavaScript中常见的几种继承方式

目录
  • 原型继承
    • 内存图
    • 分析
  • 盗用构造函数继承
    • 分析
  • 组合继承
  • 原型链继承
  • 寄生式继承
  • 寄生组合式继承

原型继承

function Parent(name) {
  this.name = name
}
Parent.prototype.getName = function(){
  return 'parentPrototype' + ' ' + this.name;
}
function Son() {
}
Son.prototype = new Parent();
console.log(new Son())

内存图

分析

原型继承的原理就是把子类的prototype指向父类的实例身上,这样做,子类就可以使用父类的属性和方法了,但是,无法初始化父类的属性,这个时候,盗用构造函数继承就出现了

盗用构造函数继承

function Parent(name) {
  this.name = name
}
Parent.prototype.getName = function(){
  return 'parentPrototype' + ' ' + this.name;
}
function Son(name) {
  Parent.call(this, name)
}

console.log(new Son('jack'))

分析

盗用构造函数的原理简单理解就是吧父类函数的代码 copy 到子类里面,在上述代码中相当于把父类的this.name = name 在子类里执行了一次,这样的话,就可以在子类实例化的时候初始化父类的一些属性

如果这样的话就取不到父类原型身上的方法了,为了解决这个问题,组合继承就出现了

组合继承

function Parent(name) {
  this.name = name
}
Parent.prototype.getName = function(){
  return 'parentPrototype' + ' ' + this.name;
}
function Son(name) {
  Parent.call(this, name) // 第二次调用
}
Son.prototype = new Parent() // 第一次调用
console.log(new Son('jack'))

组合继承,也称为伪经典继承,结合了原型继承和盗用构造函数继承,既可以初始化父类的方法,又可以取到父类的原型身上的方法

可以看到这种继承方式name会被多次创建,虽然在使用上没什么区别,但是会多开辟一些无用内存,而且还会多调用一次函数

原型链继承

const parent = {
  name: 'jack',
  getName() {
    return this.name
  }
}
const son = Object.create(parent)
console.log(son)

这种继承适用于想在一个对象的基础上添加一个新的对象,这个新的对象可以有自己独立的属性

还可以有自己的属性:

const parent = {
  name: 'jack',
  getName() {
    return this.name
  }
}
const son = Object.create(parent, {
  age: {
    value: 18,
    enumerable: true,
    writable: true,
    configurable: true
  }
})
console.log(son)

寄生式继承

const parent = {
  name: 'jack',
  getName() {
    return this.name
  }
}
function createObj(origin){
  const res = Object(origin);
  res.age = 18;
  res.getAge = function() {
    return this.age
  };
  return res
}
const son = createObj(parent)
console.log(son)

寄生式继承就是类似于工厂模式,经过它创建的函数,会有一些自带的值

寄生组合式继承

function Parent(name) {
  this.name = name;
}
Parent.prototype.getName = function () {
  return this.name;
}
function Son(name) {
  Parent.call(this, name)
};
function inhertPrototype(Son, Parent) {
  const res = Object(Parent.prototype); // 创建目标对象的原型对象
  // 可以理解为复制父类对象prototype的属性,这样做可以少调用一次父类的实例化操作
  res.constructor = Son // 将构造函数指向son
  Son.prototype = res //将子类的prototype 指向父类创建的原型对象,这样子类既可以使用父类的方法,又不用实例化父类
}
inhertPrototype(Son, Parent)
console.log(new Son('jack'))

寄生组合式继承 被称为最佳继承模式 他解决了组合继承父类函数被调用两次的问题,同时又不会给子类的prototype 加上父类的无用的属性

可以对比组合继承的图看一下,prototype 上少了 name ,最佳的继承方式

到此这篇关于JavaScript中常见的几种继承方式的文章就介绍到这了,更多相关js继承方式内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • js中常见的6种继承方式总结

    目录 前言 1.原型继承 2.盗用构造函数 3.组合继承 4.原型式继承 5.寄生式继承 6.寄生式组合继承 总结 前言 js是门灵活的语言,实现一种功能往往有多种做法,ECMAScript没有明确的继承机制,而是通过模仿实现的,根据js语言的本身的特性,js实现继承有以下通用的几种方式 温馨提示:本文中Super函数都是指父类,Sub函数都是代表子类.同时文中会涉及到“构造函数模式”和“工厂模式”,如果不熟悉的小伙伴,可以先看看这篇介绍 js常见的4种创建对象方式. 1.原型继承 实现: fu

  • JavaScript 常见的继承方式汇总

    原型链机制: 在ECMAscript中描述了原型链的概念,并将原型链作为实现继承的主要方法,其基本思想就是利用原型让一个引用类型继承另一个引用类型的属性和方法. 构造函数和原型还有实例之间的关系: 每个构造函数都有一个原型对象(prototype),原型对象都包含一个指向构造函数的指针(constructor),而实例都包含一个指向原型对象的内部指针 ( __propto__ ) .关系图如下图所示: 每一个Function都是Object基类的一个实例,所以每一个Function上都有一个__

  • JS中的六种继承方式以及优缺点总结

    目录 前言 原型链继承 构造函数继承 组合继承(原型链继承和构造函数继承组合) 寄生式继承 组合寄生式继承 extends继承 总结 前言 继承是JS世界中必不可少的一个环节,号称JS的三座大山之一,使用这种方式我们可以更好地复用以前的开发代码,缩短开发的周期.提升开发效率 在ES6之前,JS中的类都是通过构造函数模拟的,并不存在真正意义上的类,虽然ES6的类知识一个语法糖

  • 分享JavaScript 中的几种继承方式

    目录 一.原型链 1.1 原型链的问题 二.盗用构造函数 2.1 基本思想 2.2 可向父类构造函数传参 2.3 盗用构造函数的问题 三.组合继承(伪经典继承) 3.1 基本思想 3.2 组合继承的问题 四.原型式继承 4.1 基本思想 4.2 Object.create() (1)语法 (2)示例 (3)手动实现 五.寄生式继承 5.1 基本思想 5.2 寄生式继承 六.寄生式组合继承 6.1 基本思想 前言: 说到JavaScript中的继承,与之密切相关的就是原型链了,JavaScript

  • JS高级ES6的6种继承方式

    目录 1.原型链继承 2.借助构造函数继承 3.组合式继承 4.原型式继承 5.寄生式继承 6.寄生组合式继承 前言: 继承是面向对象中老生常谈的一个内容,在ECMAScript6之前,JavaScript中的继承可谓是非常的繁琐的,有各种各样的继承,本质上所有的继承都是离不开原型链的,ES6新增的extends关键字也是通过原型链实现的继承,但是语法相对来说就简单了很多. 关于原型链的内容,可以参考上篇文章两张图搞懂原型链 本篇文章就来介绍一下在ECMAScript6之前是怎么实现继承的. 1

  • JavaScript中常见的几种继承方式

    目录 原型继承 内存图 分析 盗用构造函数继承 分析 组合继承 原型链继承 寄生式继承 寄生组合式继承 原型继承 function Parent(name) { this.name = name } Parent.prototype.getName = function(){ return 'parentPrototype' + ' ' + this.name; } function Son() { } Son.prototype = new Parent(); console.log(new

  • javascript中createElement的两种创建方式

    本文实例讲述了javascript中createElement的两种创建方式.分享给大家供大家参考.具体实现方法如下: <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>CreateElement

  • js中常见的4种创建对象方式与优缺点

    目录 前言 1.工厂模式 2.构造函数模式 3.原型模式 4.Object.create() 其他模式 总结 前言 说起创建对象,最容易想到的便是通过对象字面量方式直接定义一个对象吧,但这种方式只能创建少量,单独且相互间无联系的对象.若要批量创建对象,该如何? 1.工厂模式 实现: function fn(a,b){ let obj = new Object() obj.a=a obj.b=b return obj } const test = fn(1,2) 优点:解决了创建多个类似对象的问题

  • javascript中常见的3种信息提示框(alert,prompt,confirm)

    1.警告提示框 alert("文本"). ex. function disp_alert() { alert("我是警告框!!"+'\n'+"hhah")//有折行 } [Ctrl+A 全选 注:如需引入外部Js需刷新才能执行] 2.确认提示框(confirm,返回true或者false) function show_confirm() { var r=confirm("Press a button!"); if (r==tr

  • Javascript编程中几种继承方式比较分析

    本文实例分析了Javascript编程中几种继承方式比较.分享给大家供大家参考,具体如下: 开篇 从'严格'意义上说,javascript并不是一门真正的面向对象语言.这种说法原因一般都是觉得javascript作为一门弱类型语言与类似java或c#之类的强型语言的继承方式有很大的区别,因而默认它就是非主流的面向对象方式,甚至竟有很多书将其描述为'非完全面向对象'语言.其实个人觉得,什么方式并不重要,重要的是是否具有面向对象的思想,说javascript不是面向对象语言的,往往都可能没有深入研究

  • Javascript中的几种继承方式对比分析

    开篇 从'严格'意义上说,javascript并不是一门真正的面向对象语言.这种说法原因一般都是觉得javascript作为一门弱类型语言与类似java或c#之类的强型语言的继承方式有很大的区别,因而默认它就是非主流的面向对象方式,甚至竟有很多书将其描述为'非完全面向对象'语言.其实个人觉得,什么方式并不重要,重要的是是否具有面向对象的思想,说javascript不是面向对象语言的,往往都可能没有深入研究过javascript的继承方式,故特撰此文以供交流. 为何需要利用javascript实现

  • 浅谈js中的三种继承方式及其优缺点

    第一种,prototype的方式: //父类 function person(){ this.hair = 'black'; this.eye = 'black'; this.skin = 'yellow'; this.view = function(){ return this.hair + ',' + this.eye + ',' + this.skin; } } //子类 function man(){ this.feature = ['beard','strong']; } man.pr

  • 详解C++ 中的三种继承方式

    public 方式继承 基类成员对派生类的可见性对派生类来说,基类的公有成员和保护成员可见,基类的公有成员和保护成员作为派生类的成员时,它们都保持原有的状态;基类的私有成员不可见,基类的私有成员仍然是私有的,派生类不可访问基类中的私有成员. 基类成员对派生类对象的可见性对派生类对象来说,基类的公有成员是可见的,其他成员是不可见的. 所以,在公有继承时,派生类的对象可以访问基类中的公有成员,派生类的成员函数可以访问基类中的公有成员和保护成员. 简单来说,派生类能访问基类的public, prote

随机推荐