JS 继承

什么是继承

维基百科解释:
继承的作用:是使得子类具有父类的各种属性和方法;继承是类与类之间的关系。

为什么要用继承?

网上找到的一段话:

通常在一般的项目里不需要,因为应用简单,但你要用纯 js 做一些复杂的工具或框架系统就要用到了,比如 webgis、或者 js 框架如 jquery、ext 什么的,不然一个几千行代码的框架不用继承得写几万行,甚至还无法维护

JS 里的原型继承模型

JS:没有类。(即使是ES6中的类也是语法糖)
JavaScript 是基于原型实现面向对象的,那么在JS中,面向对象概念中的继承自然也是基于原型。

当谈到继承时,JavaScript 只有一种结构:对象。每个实例对象(object )都有一个私有属性(称之为[[prototype]])指向它的原型对象(prototype)。该原型对象也有一个自己的原型对象 ,层层向上直到一个对象的原型对象为 null。根据定义,null 没有原型,并作为这个原型链中的最后一个环节。
几乎所有 JavaScript 中的对象都是位于原型链顶端的 Object 的实例

JS虽然没有传统语言意义上的类,但是 JS语言 使用构造函数生成对象,实现面向对象程序设计。

JS 中的继承到底是什么?

可以简单理解为:两次原型的搜索才叫继承

//声明 a 
a= new Arry()
// a 拥有下面两种方法,通过原型链来的
a.push()// 通过一次原型搜索 是实例属性
a.valueOf() //通过两次原型搜索;valueOf 是继承

使用prototype实现继承(ES5 )

// 构造一个 人类
function Human(name){
  this.name = name
}
// 给所有 人类 添加一个 跑 的共有属性
Human.prototype.run = function(){
  console.log("我叫"+this.name+",我在跑")
  return undefined
}
// 构造一个 男人类
function Man(name){
  Human.call(this, name)
  this.gender = '男'
}
// 所有 男人 都有好战属性
Man.prototype.fight = function(){
  console.log('糊你熊脸')
}

JS 继承_第1张图片

可以看到名为 ada 的人只有 name、gender 和fight 这些 Man 构造函数里面含有的属性,而没有我们希望的 Human 应该有的 run 的属性。
目标:假如我们有方法让 ada 有了 Man 里面没有的 run 属性,即我们自己实现了 Man 继承 Human 的过程。

prototype 的作用:为构造函数内添加实例对象之间的共有属性
Man.prototype.__proto__ = Human.prototype

JS 继承_第2张图片

可以看到 Man 指向了 Human 而不是直接指向 Object,ada2 继承了来自 Human 的 run 属性
原型链表:
JS 继承_第3张图片

但是直接操作 __ proto __ 有许多浏览器(IE)不支持。
在 IE 中,需要将

Man.prototype.__proto__ = Human.prototype // IE 不支持

换成

var f = function(){}
f.prototype = Human.prototype
Man.prototype = new f()
JS 继承_第4张图片

至此,就实现了继承,Man 有了 Human 的 属性和方法。

ES6 实现继承(class 和 extends)

 class Human{
     constructor(name){
         this.name = name
     }
     run(){
         console.log("我叫"+this.name+",我在跑")
         return undefined
     }
 }
 class Man extends Human{
     constructor(name){
         super(name)
         this.gender = '男' // 调用构造函数:'超类'
     }
     fight(){
         console.log('糊你熊脸')
     }
 }
JS 继承_第5张图片

ES6 的 class 是语法糖,其实质就是函数,而上述用 class 实现继承的过程,还是基于原型链(和 ES5 的是不是完全一致)

总结:JS 继承的原型写法相对 ES6 的写法看上去似乎更复杂,但是事实上更好理解;class 的写法更符合面向对象编程的思维,由于是语法糖因而自然写法简便,但其有一定局限性。

参考:继承与原型链

你可能感兴趣的:(JS 继承)