在构造函数中返回方法时,javascript子类化不能按预期工作

时间:2014-03-06 12:43:03

标签: javascript

我不明白为什么在以下代码中,obj.BaseMethod不返回BaseClass构造函数中定义的方法。换句话说,为什么呢

   SubClass.prototype.BaseMethod 

已定义,但

   new SubClass().prototype.BaseMethod 

未定义。

http://jsfiddle.net/HvxJ4/4/

我显然在这里缺少一些重要的东西。

function BaseClass() {
    var privatestuff = "blah";
    return {
        BaseMethod: function() {
            console.log('BaseMethod called');
        }
    }
}

function SubClass() {
    var moreprivates = "stuff";
    return {
        SubClassMethod: function() {
            console.log('SubClassMethod called');
        }
    }
}

SubClass.prototype = new BaseClass();
var obj = new SubClass();

obj.SubClassMethod(); // SubClassMethod called
obj.BaseMethod(); // Uncaught TypeError: undefined is not a function

更新

我实际上已经了解了如何使用

来运行我的代码
this.method = function() { } 

在我的构造函数中。我只是不明白为什么上面的代码没有做同样的事情。

答案是,如果在构造函数中返回一个对象,则不再使用“原型”继承。

让我最清楚的是这个答案 https://stackoverflow.com/a/2118831/834770

  

引用Douglas Crockford的第5章,继承,JavaScript:   (...)

     道格拉斯·克罗克福德随后解释了新运营商的情况   实现为JavaScript函数。这个功能利用了   书中定义的其他几个函数,所以我在一本书中重写了它   (稍微)下面简单的表格:

function createNew(constructor) {
  // a function to explain the new operator:
  //   var object = createNew(constructor);
  // is equivalent to
  //   var object = new constructor();
  //
  // param: constructor, a function
  // return: a new instance of the "constructor" kind of objects

  // step 1. create a new empty object instance
  //         linked to the prototype of provided constructor  
  var hiddenLink = function(){};
  hiddenLink.prototype = constructor.prototype;
  var instance = new hiddenLink(); // cheap trick here: using new to implement new

  // step 2. apply the constructor the new instance and get the result
  var result = constructor.apply(instance); // make this a reference to instance within constructor

  // step 3. check the result, and choose whether to return it or the created instance
  if (typeof result === 'object') {
    return object;
  } else {
    return instance;
  } 
}

因此,简而言之,如果在此函数中返回一个对象,则实际上会忽略继承位。

1 个答案:

答案 0 :(得分:1)

这是一种思考语句

的方法
new SubClass().prototype.BaseMethod

首先,new关键字告诉JavaScript创建一个新的空对象,即{}

然后,JavaScript将上下文(this)设置为等于该新对象,并在new之后调用该函数。因此,在这种情况下,JavaScript将查找要调用的函数,但您的语法不引用已定义的函数,因此结果为undefined

与使用JavaScript定义对象的典型方法形成对比:

function ExampleObject() {
    // stuff related to the example object
    this.exampleProperty = "value";
}

var exObj = new ExampleOject();

在这种情况下,new像以前一样创建空对象{},但现在有一个已定义的函数要调用。调用此函数时,新创建的对象(设置为this)将exampleProperty设置为"value"。然后将生成的对象分配给变量exObj

对于那些来自Java背景(或类似)的人来说可能听起来很奇怪,但JavaScript并不真正支持类的概念。这种语言让人不幸的选择是试图让它的典型继承看起来像经典继承,但它实际上并不相同。如果你要在JavaScript中花费大量时间,你可能想停止尝试用类和子类来思考,而是学习一些原型。