美文网首页
JS原型继承

JS原型继承

作者: 三生石上绛珠草 | 来源:发表于2017-03-15 20:52 被阅读18次

    本文适合有C++面向对象编程经验的人。
    声明:本文整理自JS高级编程,我本人没有任何原创性。

    JS用蹩脚的方式实现了面向对象的特性,虽然不喜欢,然而不得不用JS,只好也就接受这种方式。(JS面向对象像XX,既然无力反抗,就尽情享受吧)
    JS的继承有多种方式,不同方式解决了不同的问题。
    JS有一个核心原则,保证函数在实例(instance)中共享,而数据不共享。要做到这一点,则函数需要添加到prototype上,而数据则应在构造函数内部。
    (为什么函数要在实例中共享?而为什么数据不要共享?
    1.函数在JS中是对象,是占用内存空间的,最好只有一份。这一点和C语系的语言不同。C语系的函数随便定义,不占内存,反正只是执行过程。
    2.数据如果共享了,则在实例中数据就会互相影响,这是我们不想看到的,C++类的数据都是一个实例保存一份,所以JS中也需要做出这种效果。

    1.原型链继承
    这是最原始的方式,没有做一点优化。

    function SuperType(){}
    function SubType(){}
    SubType.prototype = new SuperType();
    

    这里使得父类的实例成为子类的原型,子类的实例则都可以访问到父类定义的函数。
    然而这样是会产生问题的。根据上边所说的核心原则,应该函数共享,数据不共享,而原型链继承这种原始的继承方式会导致父类数据也变成共享的了。(思考:数据怎么成共享的了?)
    而且这种继承还有一个缺点,子类无法向父类构造函数传参(向父类传参还是很有必要的,想想C++就知道)。
    2.借用构造函数法

    function SuperType(name){
      this.name = name;
      this.func = function(){}
    }
    function SubType(name){
      SuperType.call(this,name);
    }
    var instance = new SubType();
    

    缺点:函数无法复用。
    3.组合继承
    将原型链法和借用构造函数法组合起来。采二者之长,规避二者之短。

    function SuperType(name){
      this.name = name;
      this.func = function(){}
    }
    function SubType(name){
      SuperType.call(this,name);
    }
    SubType.prototype = new SuperType();
    var instance = new SubType();
    

    而JS精粹作者提出的两种方式我觉得都不好,增加记忆负担和思维负担。
    感觉他本人比较喜欢奇技淫巧,换句话说就是不朴实,虽然书写的不错,但是好多东西都增加思维负担。我一直觉得编程应该是自由的,少点条条框框反而会提升更快。我比较喜欢原理性文章,却讨厌一直被人教导你应该这样做那样做,然而并没有本质上的区别和性能上的提升。

    相关文章

      网友评论

          本文标题:JS原型继承

          本文链接:https://www.haomeiwen.com/subject/rblrnttx.html