我现在正在学习javascript,对我来说似乎是很漂亮的函数式语言,这是PHP的精彩之举,我应该早点做到这一点。虽然,我无法想出这个:
var v1 = (/[abc]/).test;
v1('a');
说test method called on incompatible undefined
,我正在尝试将该正则表达式的测试方法存储到变量中并稍后调用它。
但它适用于我自己的功能:
function foo(){
return 'I\'m foo';
}
var f = foo;
f(); // returns I'm foo
它也应该适用于方法,因为函数只是父对象的方法,对吧?
最终,我尝试这个的原因是能够写出这样的东西:
var a = ['a', 'b', 'c'];
a.every( (/[abc]/).test );
检查每个数组成员与该正则表达式。
为什么这不起作用?传递内置函数是否有限制?或者我只是做错了什么?
PS:如果你现在磨牙并闷闷不乐的做法,搞好习惯,我只是在玩。但我也想听听他们的消息。答案 0 :(得分:3)
如果只存储一个方法,它不带有对象的引用 - 它只存储对.test
方法的引用,但没有特定的对象。请记住,方法“只是”对象的属性,并且存储对方法的引用不会将其绑定到该对象,它只存储对该方法的引用。
要在特定对象上调用该方法,必须使用该对象调用它。
您可以创建自己的函数,在所需的对象上调用方法,如下所示:
var v1 = function(x) {
return /[abc]/.test(x);
}
然后,当你这样做时:
v1('a');
它将在你的函数中执行相应的操作:
/[abc]/.test('a');
但是,为什么你这样做还不完全清楚,因为你也可以定义正则表达式并多次调用.test():
var myRegex = /[abc]/;
console.log(myRegex.test('a'));
console.log(myRegex.test('b'));
console.log(myRegex.test('z'));
答案 1 :(得分:3)
它适用于我自己的功能
您没有在函数中使用this
。考虑这个例子:
var obj = {
foo: 42,
bar: function() {
alert(this.foo);
}
};
var f = obj.bar;
f(); // will alert `undefined`, not `42`
它也应该适用于方法,因为函数只是父对象的方法,对吧?
“方法”只是分配给对象属性的函数的通俗术语。功能是独立的值。与功能分配的对象没有任何关联。这怎么可能,因为一个函数可以分配给多个对象?
为什么这不起作用?
在{strong>运行时中确定函数内部this
所指的内容。因此,如果您将函数分配给变量并稍后调用
var v1 = (/[abc]/).test;
v1('a');
函数内的 this
将引用window
,而不是正则表达式对象。
您可以使用.bind
[MDN]将this
明确绑定到特定值:
var a = ['a', 'b', 'c'];
var pattern = /[abc]/;
a.every(pattern.test.bind(pattern));
请注意,由于.bind
返回一个函数,因此使用函数表达式的唯一优势是它的写入时间稍短。
传递内置函数是否有限制?
不,每个方法/函数都存在问题,因为这是函数的工作方式。关于内置函数的好处是它们经常明确告诉你何时this
指的是错误类型的对象(通过抛出错误)。
答案 2 :(得分:1)
test
函数希望this
成为正则表达式。表达式/[abc]/.test
给出了一个未绑定的函数(它不记得它属于/[abc]/
)。当您像调用它一样调用它时,this
将为undefined
,函数将失败。
您可以使用bind
让函数记住它所属的对象:
var v1 = /[abc]/.test.bind(/[abc]/);
或
var v1 = RegExp.prototype.test.bind(/[abc]/);
答案 3 :(得分:0)
您对该方法的引用已经失去了对它的方法的了解。 这不仅仅是JS工作的好方法。
你可以这样做:
var v1 = /[abc]/;
v1.test('a');
如果必须封装测试方法,那么你可以这样做:
var v1 = function(str){
return /[abc]/.test(str);
};
v1('a');
答案 4 :(得分:0)
我不知道这是否是可接受的解决方案,但您可以这样做:
v1 = function(exp) { return (/[abc]/).test(exp); }
v1('a');