Chome和Firefox阻止修改派生类'咖啡脚本中的原型

Chome and Firefox prevents the modification of a derived class's prototype in coffeescript?

本文关键字:咖啡 脚本 原型 Firefox 派生 修改 Chome      更新时间:2023-09-26

我最近一直在尝试学习CoffeeScript。当我试图理解CoffeeScript中的继承系统时,我陷入了一个有点进退两难的境地。我在Chrome 40、Internet Explorer 11和Firefox 36中尝试过这一点,但只有Internet Exporer 11的性能达到了我的预期。

CoffeeScript:中的此代码

class Muppet
    constructor: (@age, @hobby) -> # Why is this function empty?
    answerNanny: -> "Everything's cool!"
class SwedishChef extends Muppet
    constructor: (age, hobby, @mood) ->
        super(age, hobby)
    cook: -> 'Mmmm soup!'

用JavaScript:生成此代码

var Muppet, SwedishChef,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { 
    for (var key in parent) { 
        if (__hasProp.call(parent, key)) child[key] = parent[key]; 
    } 
    function ctor() { 
        this.constructor = child; 
    } 
    ctor.prototype = parent.prototype; 
    child.prototype = new ctor(); 
    child.__super__ = parent.prototype; return child; 
};
Muppet = (function() {
    function Muppet(age, hobby) {
        this.age = age;
        this.hobby = hobby;
    }
    Muppet.prototype.answerNanny = function() {
        return "Everything's cool!";
    };
    return Muppet;
})();
SwedishChef = (function(_super) {
    __extends(SwedishChef, _super);
    function SwedishChef(age, hobby, mood) {
        this.mood = mood;
        SwedishChef.__super__.constructor.call(this, age, hobby);
    }
    SwedishChef.prototype.cook = function() {
        return 'Mmmm soup!';
    };
    return SwedishChef;
})(Muppet)

以下是我在Chrome中获得的控制台输出:

muppet = new Muppet(3,4)
-> Muppet {age: 3, hobby: 4, answerNanny: function}
chef = new SwedishChef(3,4,5)
-> SwedishChef {mood: 5, age: 3, hobby: 4, constructor: function, cook: function…}
Muppet.prototype.food = "potato"
-> "potato"
muppet
-> Muppet {age: 3, hobby: 4, answerNanny: function, food: "potato"}
chef
-> SwedishChef {mood: 5, age: 3, hobby: 4, constructor: function, cook: function…}
SwedishChef.prototype.food = "fish"
-> "fish"
chef
-> SwedishChef {mood: 5, age: 3, hobby: 4, constructor: function, cook: function…}

现在看来,如果我删除__extends函数中的最后三行,特别是:

ctor.prototype = parent.prototype; 
child.prototype = new ctor(); 
child.__super__ = parent.prototype; return child;

在所有浏览器中,我可以自由地独立修改MuppetSwedishChef的原型。当这些行被放回去时,我无法以任何方式修改Chrome中派生类SwedishChef的原型。这包括修改基类Muppet的原型。修改不会传播到子类。在Firefox中,我不能修改基类或子类的原型。

从这三行来看,目的似乎是让子类的原型绑定到父类的原型,但这只在InternetExplorer11中很明显。

简单地说,我想知道我在这一切中的错误在哪里。我知道浏览器有时可能会有奇怪的实现怪癖,但我想排除我在这方面犯的任何错误。感谢所有花时间和精力阅读和回答我问题的人。

我认为您只是错误地读取了控制台输出,如中所示,属性就在那里,但它要么隐藏在省略号(...)后面,要么在__proto__属性上,您需要扩展它。

然而,我很好奇为什么您要在事后修改原型,而不是将它们包含在类定义中。CoffeeScript类的一个要点不是不需要修改它们的内部工作方式吗?

这是代码的编译版本,包括您在控制台中执行的部分。它在FireFox和Chrome中运行良好:

var Muppet, SwedishChef, chef, muppet,
  extend = function(child, parent) {
    for (var key in parent) {
      if (hasProp.call(parent, key)) child[key] = parent[key];
    }
    function ctor() {
      this.constructor = child;
    }
    ctor.prototype = parent.prototype;
    child.prototype = new ctor();
    child.__super__ = parent.prototype;
    return child;
  },
  hasProp = {}.hasOwnProperty;
Muppet = (function() {
  function Muppet(age1, hobby1) {
    this.age = age1;
    this.hobby = hobby1;
  }
  Muppet.prototype.answerNanny = function() {
    return "Everything's cool!";
  };
  return Muppet;
})();
SwedishChef = (function(superClass) {
  extend(SwedishChef, superClass);
  function SwedishChef(age, hobby, mood) {
    this.mood = mood;
    SwedishChef.__super__.constructor.call(this, age, hobby);
  }
  SwedishChef.prototype.cook = function() {
    return 'Mmmm soup!';
  };
  return SwedishChef;
})(Muppet);
muppet = new Muppet(3, 4);
chef = new SwedishChef(3, 4, 5);
Muppet.prototype.food = "potato";
console.dir(muppet);
SwedishChef.prototype.food = "fish";
console.dir(chef);