我如何使用JavaScript编写的扩展方法? [英] How do I write an extension method in JavaScript?

查看:250
本文介绍了我如何使用JavaScript编写的扩展方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I need to write a few extension methods in JS. I know just how to do this in C#. Example:

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



然后叫:

and then called by:

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



我怎么会做这样的事情在JavaScript中?

How would I do something like this in JavaScript?

推荐答案

在特定情况下,你的方法分配给 String.prototype ,就像这样:

In that specific case, you'd assign your method to String.prototype, like this:

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

或使用非枚举属性更好的 Object.defineProperty (ES5高,所以基本上,一切,但IE8和更早版本):

or better as a non-enumerable property using Object.defineProperty (ES5 and higher, so basically, everything but IE8 and earlier):

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



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

JavaScript is a prototypical language. That means that every object is backed by a prototype object. In JavaScript, that prototype is assigned either by the constructor function for the object, or by the new(ish) ECMAScript5 Object.create function.

在前者的情况下(构造函数),分配给对象的原型是由原型的属性定义构造函数。所以,如果你有称为构造函数

In the former case (the constructor function), the prototype assigned to an object is defined by the prototype property of the constructor function. So if you have a constructor function called Foo:

function Foo() {
}

...那么语句

var f = new Foo();



...受让人 Foo.prototype 来在˚F实例作为其原型对象。因此:

...assigns Foo.prototype to the f instance as its prototype object. Thus:

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.prototype ,因此增加一个属性 String.prototype 引用您的 sayHi的功能使所有字符串实例提供该功能。

So in your example, since firstName is a String instance (actually a string primitive, but don't worry, it gets automagically promoted to a String instance whenever necessary), its prototype is String.prototype, so adding a property to String.prototype that references your SayHi function makes that function available on all String instances.

DougR 在评论中指出,从C#的扩展方法的一个区别是,C#的扩展方法可以在引用被调用(如果你有一个字符串扩展方法,字符串s = NULL; s.YourExtensionMethod(); 实际工作)。这是不正确的JavaScript; 是它自己的类型,有没有原型,以供其扩展。

As DougR pointed out in a comment, one difference from C# extension methods is that C#'s extension methods can be called on null references (if you have a string extension method, string s = null; s.YourExtensionMethod(); actually works). This isn't true with JavaScript; null is its own type and there's no prototype to extend for it.

有关在这些例子中的函数名快速注意,如:

A quick note about the function names in those examples, e.g.

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

Foo.prototype.bar = function bar() {
// AND HERE -----------------^
    console.log(this.baz);
};

这形式,我们使用其中的函数表达式的使用名称在它(命名的函数表达式,又名NFE)曾经是著名的有问题(在IE8和更早版本;以及真的,真的老版本的几个其他的浏览器)。与其他一切人死亡,IE8是的的死了,就没有必要担心NFES了。 (和上面会好起来的,即使在IE8。)

That form, where we're using a function expression with a name in it (a "named function expression," aka NFE) used to be famous for having issues (on IE8 and earlier; and on really, really old versions of a couple of other browsers). With everything else being dead and IE8 being nearly dead, there's no need to worry about NFEs anymore. (And the above would be okay even in IE8.)

这篇关于我如何使用JavaScript编写的扩展方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆