2

I'm learning javascript right now, seems like beautiful functional language to me, it is wonderful move from PHP, I should have done this earlier. Although, I cannot figure this one out:

var v1 = (/[abc]/).test;
v1('a');

says test method called on incompatible undefined, I'm trying to store the test method of that regex into variable and invoke it later.

but it works with my own functions:

function foo(){
    return 'I\'m foo';
}

var f = foo;
f(); // returns I'm foo

It should work on methods too, since functions are just methods of parent object anyway, right?

Ultimately, the reason I'm trying this is to be able to write something like this:

var a = ['a', 'b', 'c'];
a.every( (/[abc]/).test );

to check each array member against that regex.

Why doesn't this work? Is it limitation in passing built-in functions around? Or am I just doing something wrong?

PS: If you grind your teeth now and muffling something about bad practices, screw good practices, I'm just playing. But I'd like to hear about them too.

4

5 回答 5

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'));
于 2013-06-12T00:25:12.030 回答
3

它适用于我自己的功能

您没有this在函数内部使用。考虑这个例子:

var obj = {
    foo: 42,
    bar: function() {
        alert(this.foo);
    }
};
var f = obj.bar;
f(); // will alert `undefined`, not `42`

它也应该适用于方法,因为函数只是父对象的方法,对吧?

“方法”只是分配给对象属性的函数的通俗术语。函数是独立的值。函数分配给的对象没有连接。这怎么可能,因为一个函数可以分配给多个对象?

为什么这不起作用?

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引用了错误类型的对象(通过抛出错误)。


了解更多关于this.

于 2013-06-12T00:29:27.107 回答
1

test函数期望this是一个正则表达式。该表达式/[abc]/.test给出了一个未绑定的函数(它不记得它属于/[abc]/)。当你像你一样调用它时,this将是undefined并且函数将失败。

您可以使用bind使函数记住它所属的对象:

var v1 = /[abc]/.test.bind(/[abc]/);

或者

var v1 = RegExp.prototype.test.bind(/[abc]/);
于 2013-06-12T00:32:20.283 回答
0

您对该方法的引用已经失去了对它是什么方法的了解。这与其说是 JS 的工作方式,不如说是好的做法。

你可以做:

var v1 = /[abc]/;
v1.test('a');    

如果你必须封装测试方法,那么你可以这样做:

var v1 = function(str){
    return /[abc]/.test(str);
};
v1('a');
于 2013-06-12T00:25:12.690 回答
0

我不知道这是否是一个可接受的解决方案,但你可以这样做:

v1 = function(exp) { return (/[abc]/).test(exp); }
v1('a');
于 2013-06-12T00:25:27.260 回答