1、继承
    常规对象继承,实例会继承原型链上一些不必要的属性与方法。如果直接将一个构造函数原型指定为构造函数原型的话,修改一类实例的原型,会影响到另一类原型的实例(因为同享同一个原型)
    怎么样实现,既继承某个构造函数的原型,又不用给实例添加不必要的属性,只继承原型对象的方法? => 找一个继承于目标原型并且干净的实例作为构造函数的原型对象
    圣杯模式

    1. function Teacher(){
    2. this.name = 'teacher'
    3. }
    4. Teacher.prototype.Tskill = 'Vue'
    5. function Student (){
    6. this.name = 'student'
    7. }
    8. //1、避免student实例继承Teacher实例的属性,所以不能将Teacher实例指定为Student的prototype
    9. //2、也不同直接将Teacher.prototype指定为Student.prototype,因为操作Student.prototype值时,
    10. //会影响到Teacher.prototype
    11. //解决方案:找一个继承于Teacher.prototype的干净实例作为Student.prototype
    12. function Buffer(){}
    13. Buffer.prototype = Teacher.prototype
    14. let buffer = new Buffer()
    15. Student.prototype = buffer
    16. var student = new Student()

    可以封装成一个函数
    tip:重新给构造函数原型对象赋值的时候,记得将constructor属性改回来,最好也记录下实际上继承的超类。

    1. function inherit(targetClass,origin){
    2. function Buffer (){}
    3. Buffer.prototype = targetClassPrototype
    4. let buffer = new targetClass()
    5. origin.prototype = buffer
    6. //将constructor属性指回原来构造函数
    7. origin.prototype.constructor = origin
    8. //再添加一个属性,指向继承的超类
    9. origin.prototype.super_class = targetClass
    10. }

    2、模块化开发
    利用立即自行函数独立作用域,有独立的空间,避免外界随意访问内部变量和污染全局。
    用一个变量接受自启动函数返回值,一般取名为init,如果不用变量接受,IFFE执行后立即销毁。

    1. var inherit = (function(){
    2. return function(targetClass,origin){
    3. function Buffer (){}
    4. Buffer.prototype = targetClassInstance
    5. let buffer = new targetClass()
    6. origin.prototype = buffer
    7. //将constructor属性指回原来构造函数
    8. origin.prototype.constructor = origin
    9. //再添加一个属性,指向继承的超类
    10. origin.prototype.super_class = targetClass
    11. }
    12. })()
    13. function Teacher (){}
    14. function Student (){}
    15. var instance = inherit(Teacher,Student)