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);
}
}