如何在JavaScript中编写扩展方法?

我需要在JS中编写一些扩展方法。 我知道如何在C#中做到这一点。 例:

public static string SayHi(this Object name) { return "Hi " + name + "!"; } 

然后调用:

 string firstName = "Bob"; string hi = firstName.SayHi(); 

我将如何在JavaScript中做这样的事情?

在这种情况下,你可以将你的方法赋值给String.prototype ,如下所示:

 String.prototype.SayHi = function SayHi() { return "Hi " + this + "!"; }; 

或更好的使用Object.defineProperty (ES5和更高版本,基本上,除了IE8和更早版本以外的所有东西)的非枚举属性:

 Object.defineProperty(String.prototype, "SayHi", { value: function SayHi() { return "Hi " + this + "!"; } }); 

JavaScript是一种典型的语言。 这意味着每个对象都由一个原型对象支持。 在JavaScript中,该原型由对象的构造函数或新的(ish)ECMAScript5 Object.create函数分配。

在前一种情况下(构造函数),赋值给对象的prototype由构造函数的prototype属性定义。 所以如果你有一个叫做Foo的构造函数:

 function Foo() { } 

…那么声明

 var f = new Foo(); 

…将Foo.prototype指定给f实例作为其原型对象。 从而:

 function Foo(b) { this.baz = b; } Foo.prototype.bar = function bar() { console.log(this.baz); }; var f = new Foo("Charlie"); f.bar(); // logs "Charlie" 

所以在你的例子中,因为firstName是一个String实例(实际上是一个string原语,但不用担心,它会自动提升为一个String实例,必要时),其原型是String.prototype ,所以添加一个属性到String.prototype引用你的SayHi函数使得所有的String实例都可以使用该函数。

正如DougR在评论中指出的那样,与C#扩展方法的一个区别是C#的扩展方法可以在null引用上调用 (如果你有一个string扩展方法, string s = null; s.YourExtensionMethod();实际工作)。 JavaScript不适用于此; null是它自己的types,没有可以扩展的原型。


有关这些示例中的函数名称的简要说明,例如

 Object.defineProperty(String.prototype, "SayHi", { value: function SayHi() { // HERE ------------^ return "Hi " + this + "!"; } }); Foo.prototype.bar = function bar() { // AND HERE -----------------^ console.log(this.baz); }; 

这种forms,我们正在使用一个函数expression式 (名称函数expression式,又名NFE),因为有问题而出名(在IE8和更早的版本上;以及真正的旧版本的一对其他浏览器)。 随着一切都死了,IE8 几乎已经死了,没有必要再担心NFE了。 (即使在IE8中,以上也是可以的)