先来一个父类
function Animal(name) { this.name = name || '' this.sleep = function () { console.log('sleep'); } }
原型链继承
function Dog() { } Dog.prototype = new Animal() //在这里继承了Animal的实例方法和原型方法,但是constructor也变成了Animal.prototype.constructor即Animal所以下面应该修改回来 Dog.prototype.constructor = Dog let dog = new Dog() dog.sleep() dog.eat()
构造继承
function Dog(){ Animal.call(this) //只能继承实例属性与实例方法,无法继承原型上的属性与方法。可以多继承 } let dog = new Dog()
实例继承
function Dog(name){ let instance = new Animal() instance.name = name ||'dog' return instance }
组合继承
function Dog(){ Animal.call(this) } Dog.prototype = new Animal() Dog.prototype.constructor = Dog
拷贝继承
function Dog(){ let animal = new Animal() for(var p in animal){ Dog.prototype[p] = animal[p] } }
寄生组合继承
function Dog(){ Animal.call(this) } (function(){ var Super = function(){} Super.prototype = Animal.prototype Dog.prototype = new Super() })() Dog.prototype.constructor = Dog
ES6
class Animal{ constructor(){ this.name = name } } class Dog extends Animal{ constructor(args){ super(args) } }
ES6继承与ES5的区别
- class 声明会提升,但不会初始化赋值。Foo 进入暂时性死区,类似于 let、const 声明变量。
- class 声明内部会启用严格模式。
- class 的所有方法(包括静态方法和实例方法)都是不可枚举的。
- class 的所有方法(包括静态方法和实例方法)都没有原型对象 prototype,所以也没有[[construct]],不能使用 new 来调用
- 必须使用 new 调用 class。
- class 内部无法重写类名。