How does javascript eval handle 'this'
I ran tests in Firefox 3.6.11, if that matters, an开发者_如何学Pythond eval misbehaves in the context of call and apply. It somehow jumps over the current 'this' object. Why?
dojo.provide("yal-js.tests.javascript");
function evaltest () {
var dis=this;
// it works now... returns 2 on call and apply
return eval("(function() {return this.testValue;}).call(dis);");
// this, however, didn't work: it returned 1, not 2
//return eval("(function() {return this.testValue;})();");
}
function controltest() {
return this.testValue;
}
var testValue=1;
var testObj={testValue: 2};
doh.register("tests.javascript",
new TFRunGroup(
["direct",
function () {doh.assertEqual(1,controltest());} ],
["call",
function() {doh.assertEqual(2, controltest.call(testObj) );}],
["apply",
function() {doh.assertEqual(2, controltest.apply(testObj) );}],
["eval direct",
function () {doh.assertEqual(1,evaltest());} ],
["eval call",
function() {doh.assertEqual(2, evaltest.call(testObj) );}],
["eval apply",
function() {doh.assertEqual(2, evaltest.apply(testObj) );}]
));
this at javascript is an object that called function,
when you use object.function()
then this
is object
,
when you use function.call(object,...)
then this
is object
,
when you use function.apply(object,...)
then this
is object,
when you use new constructor(...)
then this
is new constructed object
,
otherwise this
is the global object
in brower it is window
.
call
takes in, as its first argument, the value of this
(see here). So in the first line that works
return eval("(function() {return this.testValue;}).call(dis);");
you are passing it dis
which points to evaltest
, so this.testValue
points to evaltest.testValue
.
In the second line that doesn't work
return eval("(function() {return this.testValue;})();");
you are passing it null
for this
, so this.testValue
is set to the window's this.testValue
object.
精彩评论