使用空函数作为继承的构造函数在javascript中使用instanceof进行混乱?

时间:2014-11-19 15:32:26

标签: javascript class inheritance constructor prototype

我正在尝试创建一个简单的帮助函数来自动执行javascript继承。像这样工作:

var myClass = makeClass({
   inherit: SomeSuperClass, //optional, obviously
   constructor: function() {} // would like for this to be optional
   anotherMethod: function(){} // just gets added to the prototype chain.
   // etc
});

我让一切都运转得非常好,并且非常轻巧,但我遇到了一个错误,告诉我我并不真正理解我在做什么。根据{{​​3}}的精彩答案,我有以下内容:

function makeClass(properties) {

   // If the user doesn't supply a constructor, give them a generic function
   if ( ! properties.constructor ){
       properties.constructor = function(){};
   }


    if (properties.inherit) {
        properties.constructor.prototype = Object.create(properties.inherit.prototype);
        properties.constructor.prototype.constructor =  properties.constructor;
    }

    return properties.constructor;

    // Plus a simple loop to add the remaining methods given in properties to the prototype chain. Not important here
}

现在实施。这与预期一样有效。

var Food = makeClass({
    constructor: function(){}
});
var Bread = makeClass({
    inherit: Food,
    constructor: function(){}
});
var Sushi = makeClass({
    inherit: Food,
    constructor: function(){}
});

var bread = new Bread();
var sushi = new Sushi();

console.log(sushi instanceof Bread);  // false
console.log(bread instanceof Sushi);  // false
console.log(sushi.constructor);       // [Function: Sushi]
console.log(bread.constructor);       // [Function: Bread]
console.log(sushi instanceof Food);   // true
console.log(bread instanceof Food);   // true
console.log(sushi instanceof Sushi);  // true
console.log(bread instanceof Bread);  // true

我的问题来自面包或寿司,不提供构造函数。如果Bread没有提供构造函数,那么使用makeClass()中创建的泛型函数,那么:

(sushi instanceof Bread) become **true**

如果Sushi没有提供构造函数,那么面包就成了Sushi的一个例子。为什么会这样?我能理解他们是否都评估为真或假,但为什么删除Bread的构造函数会影响sushi实例?我想我的问题是如果它是无效的,则将一个空函数分配给properties.constructor,但我不知道如何做到这一点。

如果我想做的不可能,或者不是最佳做法,我也想知道。尽管如此,我似乎错过了一些非常基本的东西。我已经搜索过SO和Google几个小时了,似乎无法找到同样的问题。

谢谢!

1 个答案:

答案 0 :(得分:3)

  

如果Bread没有提供构造函数,那么使用在makeClass()

中创建的泛型函数

不完全是。 properties.constructor,您根据自己的条件进行测试,(almost)将始终具有值:它会从.constructor继承Object.prototype。这将使您的makeClass()来电返回Object功能,sushi确实是instanceof Object

所以这是我们需要使用hasOwnProperty method

的情况之一
…
// If the user doesn't supply a constructor, give them a generic function
if ( !properties.hasOwnProperty("constructor") ){
    properties.constructor = function(){};
}
…