1.JS实现继承的方法?
https://blog.csdn.net/u014787301/article/details/52203696
http://www.ruanyifeng.com/blog/2010/05/object-oriented_javascript_inheritance.html
小结:主要有三种继承方法:构造函数继承、原型继承、组合继承
- 构造函数继承方法:子类的构造函数调用了父类的构造函数,使用call改变父类构造函数的作用域。如果方法也通过这种方法继承的话,会使得多个实例的方法也私有化,造成资源的浪费。即,构造函数继承方法会使得子类的多个实例中从父类继承过来的属性和方法都私有化,没有实现方法的共享。
- 原型继承方法:子类的原型指向父类的实例,并将子类原型上的构造函数修正为子类的构造函数。通过原型继承方法实现的继承,子类的多个实例中从父类继承过来的属性和方法都实现了共享,没有实现属性的私有化,因此针对一个实例的属性进行修改,会影响其他实例的属性。
- 组合继承:构造函数继承和原型继承的组合,即,把想要从父类那里继承的属性利用构造函数继承的方式实现继承,把想要从父类那里继承的方法利用原型继承的方式实现继承。通过组合继承方法实现的继承,子类的多个实例中从父类继承过来的属性实现了私有化,而方法实现了共享。
----------------------------------------------------------------------细节------------------------------------------------------------------------------------------
(1)构造函数继承
只需要在子类Cat构造函数中以apply的方式调用父类的构造函数即可。这里的this是Cat执行的作用域。在使用in确保了某属性或方法肯定在该实例上以后,使用hasOwnProperty()能判断一个属性或方法是否是该实例独有的,如果是独有的,那么不同实例的该属性或方法肯定是不同的。
(2)原型继承
让子类的原型指向父类的实例,再将子类的原型上的构造函数修正回子类的构造函数,这样,所有父类上的属性和方法在子类的不同实例上都是一样的,即原型链上的属性和方法实现了共享;而子类在构造函数中声明的独有的属性和方法还是私有的。想判断一个实例上的属性或方法是独有的还是原型链上的,可以结合使用in和hasOwnProperty()方法。
(3)组合继承
结合了构造函数继承和原型继承的优点,对于从父类继承的属性都是私有的,对于方法都是共享的。写法是将父类中的属性放到构造函数中,而将父类的方法提出来放到其原型上,这样在子类的构造函数中调用父类的构造函数时就可以将父类中的属性变为私有的,而父类原型链上的方法则通过原型链传递给子类,是公有的。
(4)对上述组合继承的改进
将
Cat.prototype=new Animal()
替换为:
let F = function (){}
F.prototype=Animal.prototype
Cat.prototype=new F()
其他保持不变
关于组合继承更详细的解释,比如为什么要将子类的原型指向父类的实例,还要修复子类原型上的构造函数,以及组合继承的改进方法,可以看文章开头的第二个链接。