Javascript 将函数绑定到String.prototype,使其';他总是绑在绳子上

Javascript 将函数绑定到String.prototype,使其';他总是绑在绳子上,javascript,Javascript,此代码段确实扩展了String.prototype 它可以很好地处理函数调用,比如'foobar'。包含('foo') 但如果将其作为函数传递,而不是调用它,则无法正常工作: String.prototype.contains = function(str) { return this.indexOf(str) !== -1; }; 我知道你可以做到: var str = 'foobar'; ['foo', 'bar'].every(str.contains); TypeError:

此代码段确实扩展了
String.prototype

它可以很好地处理函数调用,比如
'foobar'。包含('foo')

但如果将其作为函数传递,而不是调用它,则无法正常工作:

String.prototype.contains = function(str) {
    return this.indexOf(str) !== -1;
};
我知道你可以做到:

var str = 'foobar';
['foo', 'bar'].every(str.contains);
TypeError: Object [object global] has no method 'indexOf'
或者类似于:

['foo', 'bar'].every(str.contains.bind(str));
但它们只会让我感到尴尬。
在我创建的
构造函数中
函数中,尽管它不是这样工作的:

['foo', 'bar'].every(function(item) { return str.contains(item); });
我可以这样做,让它工作:

function Foo(myStr) {
    this.myStr = myStr;

    this.contains = function(fragment) {
        return this.myStr.indexOf(fragment) !== -1;
    };
}
var someFoo = new Foo('foobar');
['foo', 'bar'].every(someFoo.contains)
TypeError: Cannot call method 'indexOf' of undefined
我想知道是否有一种方法可以扩展
String.prototype
,这样我就不必将
'someString.contains
绑定到
'someString'
,每次我将它作为函数使用时都不调用它。

的第二个参数是
thisArg
执行回调时使用的值)

因此,你可以:

function Foo(myStr) {
    var self = this; // Line added
    this.myStr = myStr;

    this.contains = function(fragment) {
        return self.myStr.indexOf(fragment) !== -1; // this changed to self
    };
}
要修复代码,请执行以下操作:

['foo', 'bar'].every(str.contains, str);
试试这个:

function Foo(myStr) {
    this.contains = function(fragment) {
        // myStr is accessible here
        return myStr.indexOf(fragment) !== -1;
    };
}
var someFoo = new Foo('foobar');
['foo', 'bar'].every(someFoo.contains);
它使用getter定义了一个新属性,这意味着每次“获取”函数时,例如在
['foo','bar'].every(str.contains)中str.contains
。该函数与您的函数相同,只是我们在getter中绑定了
this
,getter是字符串,这是我们想要的

如果您的浏览器(或任何使用您的代码的人)中未定义
Object.defineProperty
,您可以改用
\uuu defineGetter\uuu

完整的解决方案如下所示:

Object.defineProperty(String.prototype, "contains", {
    get: function () {
        return (function(str) {
            return this.indexOf(str) !== -1;
        }).bind(this);
    }
});
以及用法:


addPropertyWithGetter(String.prototype,“contains”)

你应该怎么做会让你感到尴尬?很难。@Jon,因为我可以像我创建的Foo类那样做。我经常使用FP,我觉得如果我没有将
contains
函数很好地绑定到字符串上,我的程序会犯很多错误,因为这种用法在我的程序中到处都有……对于字符串没有办法,我怀疑对MyString类型这样做会有用。@octref:
str.contains=str.contains.bind(str)
。但我觉得这样做不好。感觉有点不对。你可能会有一个字符串的行为与其他字符串不太一样,所以现在你必须记住它的特殊性。@Jon Yea这会在这里起作用,但这不是我想要的。我希望每当我创建一个新字符串“someString”并使用“someString”时,它都会绑定到“someString”,因为这对我来说很自然。谢谢你的回答。但是我想知道是否有一种方法可以将
contains
函数绑定到字符串,就像我将它绑定到
Foo
类一样。换句话说,当我使用str.contains.Have时,thisArg会自动绑定到str。我很抱歉,但不知怎么的,我没有看到关于你答案的通知。这很好用——非常感谢!
addPropertyWithGetter = function(object, property) {

    getter = function () {
        return (function(str) {
            return this.indexOf(str) !== -1;
        }).bind(this);
    }

    if (_.isFunction(Object.defineProperty)) {
        return Object.defineProperty(object, property, {
            get: getter,
        });
    } else {
        object.__defineGetter__(property, getter);
    }
}