如何在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中,以上也是可以的)