JS 中继承的写法

什么是继承

继承(英语:inheritance)是面向对象软件技术当中的一个概念。如果一个类别B“继承自”另一个类别A,就把这个B称为“A的子类”,而把A称为“B的父类别”也可以称“A是B的超类”。继承可以使得子类具有父类别的各种属性和方法,而不需要再次编写相同的代码。在令子类别继承父类别的同时,可以重新定义某些属性,并重写某些方法,即覆盖父类别的原有属性和方法,使其获得与父类别不同的功能。另外,为子类追加新的属性和方法也是常见的做法。 一般静态的面向对象编程语言,继承属于静态的,意即在子类的行为在编译期就已经决定,无法在运行期扩展。

根据维基百科解释,可以简单概括为:
继承是类与类之间的关系,其作用是使得子类具有父类别的各种属性和方法。


JS 里的原型继承模型

js是一门动态语言,js没有类的概念,ES6 新增了class 关键字,但只是语法糖,JavaScript 仍旧是基于原型。

至于继承,js的继承与java这种传统的继承不一样.js是基于原型链的继承. 两次的原型搜索就是继承。
数组 a 从 Array 中原型搜索到 toString 属性,只是实例属性;a 从 Array 中原型搜索到 (Array 从 Object 中原型搜索到的)valueOf 属性,可以称为继承。

  1. 使用 prototype 实现继承
    prototype 的作用:为构造函数内添加实例对象之间的共有属性

明确 JS 内的继承
以下面代码为例

// 构造一个 人类
function Human(name){
  this.name = name
}
// 给所有 人类 添加一个 跑 的共有属性
Human.prototype.run = function(){
  console.log("my name is "+this.name+",i'm running")
  return undefined
}
// 构造一个 男人类
function Man(name){
  Human.call(this, name)
  this.gender = 'man'
}
// 所有 男人 都有好战属性
Man.prototype.fight = function(){
  console.log('fight')
}
prototype

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

var a = function(){}
a.prototype = Human.prototype
Man.prototype = new a()
prototype2

可以看到 hhh 继承了来自 Human 的 run 属性

2. ES6 实现继承

上面代码的 ES6 版本

// ES6 写法
class Human{
     constructor(name){
         this.name = name
     }
     run(){
         console.log("my name is"+this.name+",i'm running")
         return undefined
     }
 }
 class Man extends Human{ // extends 实现上述继承过程
     constructor(name){
         super(name) // 调用构造函数:'超类'
         this.gender = 'man'
     }
     fight(){
         console.log('fight')
     }
 }

ES6 的 class 是语法糖,其实质就是函数,而上述用 class 实现继承的过程,还是基于原型链的, 只是更加方便我们使用继承的方法


总结:

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

参考资料:

MDN继承与原型链
Class 的继承

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