【问题标题】:Javascript constructor functions in "subclass", correct notation?“子类”中的Javascript构造函数,正确的符号?
【发布时间】:2016-09-21 17:20:15
【问题描述】:

我正在尝试处理 javascript 继承。我的示例代码是这样开始的:

var example = example || {};
example.Classes = {};

(function() {
    var example = example || {};
    example.Classes = {};

    var privateVar = 25;
    function Superclass() {
        this.x = privateVar;
    }
    Superclass.prototype = {
        move: function(x){
            this.x += x;
            console.log("Superclass move",this.x);
        },
        dance: function(x){
            this.x += x*2;
        }
    };

    function Subclass() {
        Superclass.apply(this, arguments);
        this.y = 0;
    };
    Subclass.prototype = Object.create(Superclass.prototype);
    Subclass.prototype.constructor = Subclass;

这是成功的延续:

    Subclass.prototype.dance = function(x, y) {
      this.x -= (x + privateVar);
      this.y -= y;
      console.log("Subclass dance", this.x, this.y)
    };
    example.Classes.Superclass = Superclass;
    example.Classes.Subclass = Subclass;
    window.example.Classes = example.Classes;
}());

var success = new example.Classes.Subclass();
success.dance(5,4);
success.move(6);

控制台输出:子类 dance -5 -4
控制台输出:超类移动 1


现在失败的延续 - 这里有什么问题?为什么不能用这种方式写子类构造函数?

    Subclass.prototype = {
        dance: function(x, y) {
            this.x -= (x + privateVar);
            this.y -= y;
            console.log("Subclass dance", this.x, this.y)
        }
    };

    example.Classes.Superclass = Superclass;
    example.Classes.Subclass = Subclass;
    window.example.Classes = example.Classes;
}());

var failure = new example.Classes.Subclass();
failure.dance(5,4);
failure.move(6);  

控制台输出:子类 dance -5 -4
控制台输出:错误:failure.move 不是函数

【问题讨论】:

  • 我建议阅读this page on MDN。你不应该需要所有的 Classes/Subclass/Superclass 东西......
  • 所以我的问题归结为Subclass.prototype.dance = function(x, y){}; 和Subclass.prototype = {dance:function(){}}; 之间的区别是什么?

标签: javascript function inheritance prototype


【解决方案1】:

为什么不能用这种方式写子类构造函数?

因为您正在炸毁曾经位于 Subclass.prototype 属性上的对象(来自 Object.create(Superclass.prototype) 的那个),并将其替换为原型为 Object.prototype 的对象一个属性,dance。

一旦您创建了Subclass.prototype 对象,您总是希望像原来一样扩充它:

Subclass.prototype.dance = /*...*/;

不是替换它:

// Not this
Subclass.prototype = { dance: /*...*/ };

ES2015 添加了一个方便的功能,用于将一个对象(或一系列对象)中的属性合并到目标对象中:Object.assign。它可以(大部分)为旧的 JavaScript 引擎填充。使用它,你可以这样做:

Object.assign(Subclass.prototype, {
    dance: function dance() { /* ... */ },
    skip:  function skip()  { /* ... */ },
    jump:  function jump()  { /* ... */ }
});

话虽如此,在 2016 年,我建议使用 ES2015 中添加的 class 功能(必要时为旧版 JavaScript 引擎进行转译):

class Superclass {
    constructor() {
        //...
    }

    method() {
        // ...
}

class Subclass extends Superclass {
    constructor() {
        super();
        // ...
    }

    anotherMethod() {
        // ...
    }
}

【讨论】:

  • 谢谢,这很有帮助!
猜你喜欢
  • 2014-03-08
  • 2017-06-10
  • 1970-01-01
  • 2016-05-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-10
  • 2020-10-22
相关资源
最近更新 更多