Assigning Regexp.test To A Variable
Solution 1:
It has to do with the value of this
inside the test
method.
For example:
var obj = {
method: function () { returnthis === obj }
};
obj.method(); // truevar method = obj.method;
method(); // false
If you call the test
method "as a function" -as your example r();
-, the this
value will refer to undefined
(for built-in or strict functions in ECMAScript 5, in the above example this
will refer to the global object).
Calling any method of RegExp.prototype
with a this
value that is not a RegExp
object, will always generate this TypeError
exception, quoting the spec:
15.10.6 Properties of the RegExp Prototype Object
In the following descriptions of functions that are properties of the RegExp prototype object, the phrase “this RegExp object” refers to the object that is the this value for the invocation of the function; a TypeError exception is thrown if the this value is not an object or an object for which the value of the [[Class]] internal property is not "RegExp".
However you could bind the test
method to your r
function, using the Function.prototype.bind
method:
var re = /^[0-9A-Z]$/,
r = re.test.bind(re);
r("A"); // true
Or using call
or apply
:
var r = re.test;
r.call(re, "A"); // true
Solution 2:
As I've been essentially trying to answer this question in all my comments, let's summarize everything we've covered so far in an actual answer.
When you do this:
var r = /^[0-9A-Z]$/.test;
you are assigning the method named test
from the RegExp
object to the variable named r
. It is just a method assignment. There is no connection whatsoever with the specific regular expression object that you created. If fact, r == RegExp.prototype.test
.
When you then try this line of code:
r("A")
you are trying to execute RegExp.prototype.test
and passing it "A"
, but you have no appropriate object context. When the test function runs, the this
pointer won't point to a regular expression object, it will point to the global object (which in a browser is the window
object).
In your o, a and b code example, it works because all you're doing is calling functions that refer to no instance data and the this pointer is not used at all (therefore it doesn't matter that it's not set to an appropriate object context). That isn't the case with the regular expression method. It needs its instance data (e.g. it's this
pointer to point to a real regular expression object).
It is possible to take a method point and add the appropriate this
pointer, though I have no idea why that would be useful in this particular example. For example, you could do this:
var re = /^[0-9A-Z]$/;
var r = re.test;
r.call(re);
That sets the this
pointer to your regular expression object and then executes the r
method with that this
pointer.
I don't really know why you'd want to do that, but hopefully that helps explain things.
Solution 3:
MAJOR EDIT: Now that I've seen your update, which removed the problem my original post talked about, I realise that the problem is the test
function needs to be associated to an object when it runs. Standard dot notation after a regex object will automatically set this
within test
equal to that object. When you call it by itself as r("A");
then this
will be set to the window object, which doesn't work and gives an error. (This wouldn't matter for some functions, but test
needs its this
object to be a regex to operate on.)
You can make it work by explicitly setting the this
using .call()
:
var re = /^[0-9A-Z]$/;
var rf = re.test;
alert(rf.call(re,"A")); // displays 'true'alert(rf.call(/blah/,"A")); // displays 'false'
But that seems pretty silly. I'd ask why you can't just do this:
var r = /^[0-9A-Z]$/;
r.test("A");
r.test("B");
This lets you keep one copy of the regex, and you don't need your own function wrapper. If you really want the r("A")
syntax just add a wrapper.
Post a Comment for "Assigning Regexp.test To A Variable"