js几种继承方式

注意:

1,constructor总是指向类的构造函数

2,__proto__指向父类的原型对象

1,原型链继承


function Father(name){

    this.name=name;

    this.color=['red','blue'];

}

Father.prototype.getName=function(){

    console.log(this.name)

}

function Child(){}

Child.prototype = new Father();

Child.prototype.constructor = Child;

var son1 = new Child('ming');

var son2 = new Child('wei');

son1.color.push('white');

son2.color; //['red','blue','white']

缺点:对于复杂数据类型color,多个实例对引用的操作会被篡改

2,借用构造函数继承


function Father(name){

    this.name=name;

}

Father.prototype.getName=function(){

    console.log(this.name)

}

function Son(name){

    Father.apply(this,arguments);

}

var son = new Son('ming');

console.log(son.getName())  // son.getName is not a function

缺点:父类原型链上的属性和方法无法获取

3,组合继承(伪经典继承)


function Father(name) {

    this.name = name;

    this.color=['red','blue'];

}

Father.prototype.getName = function() {

    console.log(this.name)

}

function Child(name) {

    Father.apply(this, arguments);

}

Child.prototype = new Father();

Child.prototype.constructor = Child;

var son = new Child('ming');

console.log(son.color);

son.color.push('white') 

var son2 = new Child('wei');

console.log(son2.color)    //['red','blue']

基本ok,除了new Father()那个地方会多写一遍属性和方法,差不多还行

4,原型式继承(道爷-2006)


var Person={

    name:'ming',

    color:['red','blue']

}

function object(obj){

    function F(){};

    F.prototype=obj;

    return new F();

}

var son1 = object(Person);

var son2 = object(Person);

son1.name='wei';

son1.color = ['white'];

console.log(son2.color);  // ['red','blue','white']

缺点很明显:

1,原型实例指向的引用相同,可能存在篡改

2,不能传递参数

另:object方法已经由Object.create()实现

5,寄生式继承,(道爷有点皮)

创建一个函数,在内部构造新的属性和方法,以增强对象(原型式继承的加强版)


var Person = {

    name: 'ming',

    color: ['red', 'blue']

}

function object(obj) {

  function F() {};

      F.prototype = obj;

      return new F();

  }

  function createSon(obj){

      var son = object(obj);

      console.log(son)

      son.say=function(){

      console.log('Hello,'+this.name)

    }

 return son;

}

var son1 = createSon(Person);

console.log(son1.name)

缺点很明显:

1,原型实例指向的引用相同,可能存在篡改

2,不能传递参数

6,寄生组合式继承(借用构造函数继承+寄生式继承)


function object(obj) {

    function F() {};

    F.prototype = obj;

    return new F();

}

function inheritPerson(Person,Son){

    var pro = object(Person.prototype);

    Son.prototype.constructor=Son;

    Son.prototype = pro;

}

function Person(name){

    this.name=name;

    this.color=['red','blue'];

}

Person.prototype.say=function(){

    console.log('Hello,'+this.name)

}

function Son(name,age){

    Person.call(this,name);

    this.age = age;

}

inheritPerson(Person,Son);

Son.prototype.getAge=function(){

    console.log(this.age);

}

var child1 = new Son('ming',20);

var child2 = new Son('wei',30);

child1.say()  // ming

child1.color.push('white');

console.log(child2.color)  //['red','blue']

这个是es5的终极解决方案

7,混入方式继承多个对象


function Father1(name){this.name=name}

function Father2(age){this.age=age}

function Son(name,age){

    Father1.call(this,name);

    Father2.call(this,age);

}

Son.prototype = Object.create(Father1.prototype);

Object.assign(Father1.prototype,Father2.prototype);

Son.prototype.constructor=Son;

var son1 = new Son('ming',20);

console.log(son1)

这个实际上是寄生组合式继承的加强版

8.class继承


class Person{

  constructor(name){

  this.name=name

  }

  say(){

  console.log(this.name)

  }

}

class Son extends Person{

  constructor(name){

    super(name)

    }

}

使用babel转义为es5之后:


"use strict";

function _inheritsLoose(subClass, superClass) {

    subClass.prototype = Object.create(superClass.prototype); 

    subClass.prototype.constructor = subClass;

    subClass.__proto__ = superClass;

}

var Person =

function () {

  function Person(name) {

    this.name = name;

  }

  var _proto = Person.prototype;

  _proto.say = function say() {

    console.log(this.name);

  };

  return Person;

}();

var Son =

function (_Person) {

  _inheritsLoose(Son, _Person);

  function Son(name) {

    return _Person.call(this, name) || this;

  }

  return Son;

}(Person);

总结:

1,类方法调用时不会变量提升:

var p = new P(); // Cannot access 'P' before initialization

class P{}

2,es6的继承,实际上是先创建父类的实例对象this,然后再用子类的构造函数修改this,因此在子类的contructor中要调用父类的super(),否则要报错。

参考资料:

1,https://juejin.im/post/5bcb2e295188255c55472db0#heading-0

2,https://www.liaoxuefeng.com/wiki/1022910821149312/1023021997355072

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,236评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,867评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,715评论 0 340
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,899评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,895评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,733评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,085评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,722评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,025评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,696评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,816评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,447评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,057评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,254评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,204评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,561评论 2 343

推荐阅读更多精彩内容

  • (注1:如果有问题欢迎留言探讨,一起学习!转载请注明出处,喜欢可以点个赞哦!)(注2:更多内容请查看我的目录。) ...
    love丁酥酥阅读 1,332评论 4 8
  • js 实现继承的方式有: 原型链继承; 构造函数继承; 组合继承(原型链继承 + 构造函数继承)(最常用);(原型...
    黎贝卡beka阅读 1,455评论 0 0
  • 前言 上篇文章详细解析了原型、原型链的相关知识点,这篇文章讲的是和原型链有密切关联的继承,它是前端基础中很重要的一...
    OBKoro1阅读 1,008评论 0 0
  • 博客内容:什么是面向对象为什么要面向对象面向对象编程的特性和原则理解对象属性创建对象继承 什么是面向对象 面向对象...
    _Dot912阅读 1,401评论 3 12
  • js的继承有6种方式,大致总结一下它们各自的优缺点,以及它们之间的关系。 1.原型链 js的继承机制不同于传统的面...
    XiaoAM阅读 482评论 0 1