JavaScript:将原型方法添加到内部类

JavaScript: Add prototype methods to inner class

本文关键字:添加 内部类 方法 原型 JavaScript      更新时间:2023-09-26

我想向内部类的原型添加一个方法。这可能吗?

这是我尝试过的:

var Foo = function Foo() {};
Foo.prototype = {
    Bar: function Bar() { },
    Bar.prototype: { // <- this does not work
        barMethod: function () {
            console.log('hello');
        }
    },
    fooMethod: function () {
        var bar = new this.Bar();
        bar.barMethod();
    }
}
var foo = new Foo();
foo.fooMethod();

但是Bar.prototype不起作用,它会抛出一个语法错误,并带有消息Unexpected token .

你的问题是你正在定义 Foo.prototype 对象,因此,你受对象创建的规则和语法的约束,例如,解析器希望你以key: value, nextkey: nextvalue格式列出属性,而 Bar.prototype 不适合。(键实际上是字符串,在其中使用 . 是没有意义的,因为它们会在解析时产生歧义*)

试试这个:

var Foo = function Foo() {};
Foo.prototype.Bar = function Bar() { };
Foo.prototype.Bar.prototype = {
    barMethod: function () {
        console.log('hello');
    }
};
不过,语义上略有

不同,因为这样你就不会覆盖原型,只是扩展它。(考虑先将其等于{},然后使用您尝试创建的对象的每个属性对其进行扩展)


(*) 关于歧义的说明:我在上面提到,在对象键中有一个.会产生歧义,这里有一个简单的例子:

var foo = {
   bar: {
       baz: 0,
       qux: 20
   },
   bar.baz: 150 //note that this will throw an error
};
console.log(foo.bar.baz);

如果上面的这段代码不会引发错误,您希望console.log(foo.bar.baz)打印什么,0 还是 150?

这就是为什么在密钥中使用.没有意义的原因,这就是为什么解析器在任何.上抛出意外的令牌错误。

当然,您可以使用"bar.baz"字符串作为"bar.baz": 150上面的键(请不要!),但是您必须将该值引用为

foo["bar.baz"]

这将与

foo.bar.baz;

总而言之,这只是一些基于直觉的推理,为什么你不能在密钥中使用.,但真正的原因显然是这样的:因为解析器会抛出错误。

在对象文本中,只能定义该对象文本的属性,而不能定义值的属性。

但是,如果要在创建对象时设置prototype,请考虑Object.assign(可以填充

):
Foo.prototype = {
  Bar: Object.assign(function Bar() { }, {
    prototype: {
      barMethod: function () {
        console.log('hello');
      }
    }
  }),
  fooMethod: function () {
    var bar = new this.Bar();
    bar.barMethod();
  }
};

但是,请注意,替换所有原型是一种不好的做法,因为会擦除 constructor 属性。