js继承的几种方式

1 原型链继承

function Person () { // 父级构造函数
    this.name = 'zhangsan';
    this.age = 23
  }
  function Son () { // 子级构造函数
    this.num = 50
  }
  Son.prototype = new Person()

  Son.constructor = Son

  Son.prototype.count = 50
  
  var son = new Son()
  console.log(son.name, son.age, son.num)

把子类的prototype指向父级的实例,也就是原型链继承

此继承方法优

简单明了,父级新增的属性和方法子级都能够访问的到

此继承方法缺点

就是多个子类共享一个原型的属性和方法,无法实现多个继承

2,构造函数继承

// 构造函数继承
  // 构造函数继承
  function Person () {
    this.name = 'zhangsan'
    this.age = 23
  }
  Person.prototype.count = 50 
  function Son () {
    Person.apply(this)
    this.num = 18
  }

  var son = new Son()

  console.log(son.name) // zhangsan
  console.log(son.age)  // 23
  console.log(son.count)// undefined

构造函数继承就是在子级构造函数里面执行父级的构造函数并且改变this的指向

构造函数继承的优点:

子级直接继承父级构造函数的属性和方法

构造函数继承的缺点:

子类无法继承父类原型链上的属性和方法

3,混合继承

// 混合继承
  function Person () {
    this.name = 'zhangsan'
    this.age = 23
  }
  Person.prototype.count = 50 
  function Son () {
    Person.apply(this)
    this.num = 18
  }
  Son.prototype = new Person()
  var son = new Son()

  console.log(son.name) // zhangsan
  console.log(son.age)  // 23
  console.log(son.count)// 50

混合继承就是集合原型链继承和构造函数继承两者的优点集合在一起,集二者优点与一身

优点:

集合了原型链继承和构造函数继承的优点集合在一起

缺点:

子类会拥有两个原型链属性,不过可以忽略不计;

4,原型式继承

临时创建一个构造函数,利用临时构造函数的原型,在此基础上实例化对象;

// 原型是继承;
  function object(o){
    function F(){}
    F.prototype = o;
    return new F();
  } 

  var person = {
    name: 'zhangsan',
    friend: ['111', '222', '333']
  }
  var son = object(person)
  son.name = 'lisi'
  son.friend.push('444')

  console.log(son.name) // lisi
  console.log(son.friend) // '111', '222', '333', '444'

  var son2 = object(person)
  console.log(son2.name) // zhangsan
  console.log(son2.friend) // '111', '222', '333', '444'

缺点:

原型的引用类型会在各实例化对象中共享,一旦修改其中一个就会污染其他实例;

Object.create()方法

ES5通过Object.create()方法规范了原型式继承,可以接受两个参数,一个是用作新对象原型的对象和一个可选的为新对象定义额外属性的对象,行为相同,基本用法和上面的object一样,除了object不能接受第二个参数以外

var person = {
    name: 'Jiang',
    friends: ['Shelby', 'Court']
  }
  var anotherPerson = Object.create(person)
  console.log(anotherPerson.friends) // "Shelby", "Court"

5,寄生式继承;

寄生式继承的思路与寄生构造函数和工厂模式类似,即创建一个仅用于封装继承过程的函数

function createSuper (o) {
    var clone = Object.create(o) // 创建一个新对象
    clone.fn = function () {
      console.log('hello')
    }
    return clone
  }

  var person = {
    name: 'Jiang'
  }

  var anotherPeson = createSuper (person)
  anotherPeson.fn() // hello

基于person返回了一个新对象anotherPeson,新对象不仅拥有了person的属性和方法,还有自己的fn方法

6,寄生式组合函数;

使用寄生式组合模式相当于规避了混合继承里面重复父类实例的属性和方法在子类实例和原型里面重复出现;
基本思路是不必为了子类的原型而调用父类的构造函数,我们需要的只是父类原型的一个副本;
核心概念就是利用寄生式继承父类的原型,再把结果指定给子类的原型;

// 寄生式继承的方法;
  function createSuper(son, person) {
    var prototype = Object.create(Person.prototype);
    prototype.constructor = Son;
    Son.prototype = prototype;
  }
  function Person () {
    this.name = 'zhangsan'
    this.age = 23
  }
  Person.prototype.count = 50
  function Son () {
    // 继承属性
    Person.call(this, name)
    this.num = 18
  }
  createSuper(Son, Person)
  var son = new Son()

  console.log(son.name) // zhangsan
  console.log(son.age) // 23
  console.log(son.num) // 18
  console.log(son.count) // 50

  function Son2 () {

  }
  createSuper(Son2, Person)
  var son2 = new Son2()
  son2.count = 80

  console.log(son.count) // 50
  console.log(son2.count) // 80

在createSuper()函数中所做的事:

在createSuper函数中用到了ES5的object.create()方法,将超类型的原型指定为一个临时的空构造函数的原型,并返回构造函数的实例。
此时由于构造函数内部为空(不像Person里面有实例属性),所以返回的实例也不会自带实例属性,这很重要!因为后面用它作为Son 的原型时,就不会产生无用的原型属性了,借调构造函数也就不用进行所谓的“重写”了。
然后为这个对象重新指定constructor为Son ,并将其赋值给Son 的原型。这样,就达到了将超类型构造函数的实例作为子类型原型的目的,同时没有一些从Person继承过来的无用原型属性。

优点:

继承了混合继承的优点,避免了出现重复多个原型链属性

缺点:

感觉没什么缺点,如果非说有缺点,个人感觉就是不好理解

7,Es6的class继承

// Es6 class类的继承
  class Person {
    constructor (name, age) {
      this.name = name
      this.age = age
    }
    fn () {
      console.log(this.name)
    }
  }
  // let person = new Person('zhangsan', 23)
  // person.fn()
  class Son extends Person {
    constructor (name, age, count) {
      super(name, age)
      this.count = count
    }
    fn1 () {
      console.log(this.name, this.count)
    }
  }
  var son = new Son('小花', 18, 50)
  var son2 = new Son('小红', 20)
  son.fn() // 小花
  son.fn1() // 小花 50
  son2.fn() // 小红
  son2.fn1() // 小红 undefined

缺点:

就是兼容性

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

推荐阅读更多精彩内容

  • 1. 原型继承(最常用) 让子类继承父类的方法:让子类的原型等于父类的实例 子.peototype=new 父 A...
    Mr无愧于心阅读 325评论 0 1
  • 在我近三年的职业生涯中,老实说,我很少需要自己去写一个类,然后继承,然后如何如何去调用这些方法,除了有一次公司紧急...
    0月阅读 1,621评论 0 4
  • JS继承的几种方式 (1) 属性拷贝 存在问题: 如果继承过来的成员是引用类型的话,那么这个引用类型的成员在父对象...
    __越过山丘__阅读 22,104评论 2 16
  • (注1:如果有问题欢迎留言探讨,一起学习!转载请注明出处,喜欢可以点个赞哦!)(注2:更多内容请查看我的目录。) ...
    love丁酥酥阅读 1,332评论 4 8
  •   面向对象(Object-Oriented,OO)的语言有一个标志,那就是它们都有类的概念,而通过类可以创建任意...
    霜天晓阅读 2,092评论 0 6