【问题标题】:Use switch statement for identifying type of instance of object - not working使用 switch 语句来识别对象实例的类型 - 不起作用
【发布时间】:2016-12-13 04:29:09
【问题描述】:

我尝试关注this previous question

var Animal = function(){}

var Dog = function(){}
Dog.prototype = Object.create(Animal.prototype);

var dog = new Dog();

switch(dog.constructor){
    case Dog:
        console.log("Good Dog")
        break;
    default:
        console.log("Bad Dog");
}

它记录了“Bad Dog”。

我做错了什么?

【问题讨论】:

  • 使用dog instanceof Dog
  • @Deryck 在这种情况下,dog instanceof dogdog instanceof Animal 都会产生真实的结果。
  • @Ayan ...这就是为什么它的顺序是Dog 然后default。如果它只是一个Animal,它就不会是一个instanceof Dog

标签: javascript


【解决方案1】:

由于原型继承,构造函数引用被覆盖。检查以下sn-p中的日志。

var Animal = function() {}
Animal.prototype.disp = function () {
  return 'I am an Animal';
}
var Dog = function() {}
Dog.prototype = Object.create(Animal.prototype);

var someOtherAnimal = new Dog();
// On inheriting the prototypal chain, the constructor is overridden.
console.log(someOtherAnimal.constructor === Animal);
// over riding the constructor
Dog.prototype.constructor = Dog;

var someAnimal = new Dog();
console.log(someAnimal.constructor === Dog);

switch (someAnimal.constructor) {
  case Dog:
    console.log("Good Dog")
    break;
  default:
    console.log("Bad Dog");
}
// access the animal prototpe.
console.log(someAnimal.disp());

【讨论】:

    【解决方案2】:

    使用将Dog 的原型设置为Animal.prototype 的新实例会覆盖Dog 的构造函数。这就是典型的继承模式的原因。

    var Foo = function () {};
    var Bar = function () {};
    Bar.prototype = Object.create(Foo.prototype);
    Bar.prototype.constructor = Bar;
    

    在您当前的代码Dog.constructor === Animal 中。像上面那样修改它会给你你想要的行为。

    【讨论】:

    • 啊,太好了,谢谢。这样做有什么副作用吗?它会在任何情况下改变行为吗? IE。在设置 Bar.prototype.constructor = Bar 时,除了我在 switch 语句中使用它之外,该属性是否曾以任何方式使用过?
    • @Jodes 您的代码可能不会按照您期望的方式工作,它目前的编写方式。 new 运算符实际上将调用Animal 的构造函数,而不是Dog。那是因为当你用Object.create 覆盖Dog 的原型时,它也覆盖了它的构造函数。这就是您需要将Dog 的构造函数设置回自身的原因。如果这让你感到困惑,我会阅读更多关于 JavaScript 的 prototype chain 的内容 - 掌握窍门可能会很棘手。 :)
    【解决方案3】:

    删除线

    Dog.prototype = Object.create(Animal.prototype);
    

    要创建的 Object 似乎为 Dog 类赋予了 Object 类的类型。有一种方法可以通过

    来确定对象的类名
    Object.prototype.toString.call(obj)
    

    它返回以下格式的字符串:'[object ' + valueOfClass + ']',例如 [object String] 或 [object Array]。在您的情况下,它不是返回 Dog 类,而是返回 Object 类,因为最上面的行覆盖了您的 Dog 类。

    为了将 Animal 类的继承保留到 Dog Class 中,并根据 Harangue 的回答获得所需的结果,请将行放在继承下面。

     Dog.prototype = Object.create(Animal.prototype);
     Dog.prototype.constructor = Dog; 
    

    https://jsfiddle.net/byaqbuue/3/

    【讨论】:

    • 这将删除DogAnimal 的继承,这似乎是问题中的要求。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-25
    • 2014-06-19
    • 1970-01-01
    相关资源
    最近更新 更多