javascript - How does the "this" keyword work? -
i have noticed there doesn't appear clear explanation of this
keyword , how correctly (and incorrectly) used in javascript on stack overflow site.
i have witnessed strange behaviour , have failed understand why has occurred.
how this
work , when should used?
i recommend reading mike west's article scope in javascript (mirror) first. excellent, friendly introduction concepts of this
, scope chains in javascript.
once start getting used this
, rules pretty simple. ecmascript standard defines this
keyword that:
evaluates value of thisbinding of current execution context;
(§11.1.1). thisbinding javascript interpreter maintains evaluates javascript code, special cpu register holds reference object. interpreter updates thisbinding whenever establishing execution context in 1 of 3 different cases:
initial global execution context
this case javascript code evaluated when
<script>
element encountered:<script type="text/javascript">//<![cdata[ alert("i'm evaluated in initial global execution context!"); settimeout(function () { alert("i'm not evaluated in initial global execution context."); }, 1); //]]></script>
when evaluating code in initial global execution context, thisbinding set global object,
window
(§10.4.1.1).entering eval code
... direct call eval()
thisbinding left unchanged; same value thisbinding of calling execution context (§10.4.2(2)(a)).
... if not direct call eval()
thisbinding set global object as if executing in initial global execution context (§10.4.2(1)).
§15.1.2.1.1 defines direct call eval() is. basically,
eval(...)
direct call whereas(0, eval)(...)
orvar indirecteval = eval; indirecteval(...);
indirect call eval(). see chuckj's answer (1,eval)('this') vs eval('this') in javascript? , this blog post dmitry soshnikov when might use indirect eval() call.entering function code
this occurs when calling function. if function called on object, such in
obj.mymethod()
or equivalentobj["mymethod"]()
, thisbinding set object (obj
in example; §13.2.1). in other cases, thisbinding set global object (§10.4.3).the reason writing "in other cases" because there 8 ecmascript 5 built-in functions allow thisbinding specified in arguments list. these special functions take so-called thisarg becomes thisbinding when calling function (§10.4.3).
these special built-in functions are:
function.prototype.apply( thisarg, argarray )
function.prototype.call( thisarg [ , arg1 [ , arg2, ... ] ] )
function.prototype.bind( thisarg [ , arg1 [ , arg2, ... ] ] )
array.prototype.every( callbackfn [ , thisarg ] )
array.prototype.some( callbackfn [ , thisarg ] )
array.prototype.foreach( callbackfn [ , thisarg ] )
array.prototype.map( callbackfn [ , thisarg ] )
array.prototype.filter( callbackfn [ , thisarg ] )
in case of function.prototype functions, called on function object, rather setting thisbinding function object, thisbinding set thisarg.in case of array.prototype functions, given callbackfn called in execution context thisbinding set thisarg if supplied; otherwise, global object.
those rules plain javascript. when begin using javascript libraries (e.g. jquery), may find library functions manipulate value of this
. developers of javascript libraries because tends support common use cases, , users of library typically find behavior more convenient. when passing callback functions referencing this
library functions, should refer documentation guarantees value of this
when function called.
if wondering how javascript library manipulates value of this
, library using 1 of built-in javascript functions accepting thisarg. you, too, can write own function taking callback function , thisarg:
function dowork(callbackfn, thisarg) { //... if (callbackfn != null) callbackfn.call(thisarg); }
edit:
i forgot special case. when constructing new object via new
operator, javascript interpreter creates new, empty object, sets internal properties, , calls constructor function on new object. thus, when function called in constructor context, value of this
new object interpreter created:
function mytype() { this.somedata = "a string"; } var instance = new mytype(); // kind of following, there more steps involved: // var instance = {}; // mytype.call(instance);
quiz: fun, test understanding following examples.
to reveal answers, mouse on light yellow boxes.
what value of
this
@ line a? why?<script type="text/javascript"> if (true) { // line } </script>
window
line evaluated in initial global execution context.
what value of
this
@ line b when obj.staticfunction() executed? why?<script type="text/javascript"> var obj = { somedata: "a string" }; function myfun() { // line b } obj.staticfunction = myfun; obj.staticfunction(); </script>
obj
when calling function on object, thisbinding set object.
what value of
this
@ line c? why?<script type="text/javascript"> var obj = { mymethod : function () { // line c } }; var myfun = obj.mymethod; myfun(); </script>
window
in example, javascript interpreter enters function code, because
myfun
/obj.mymethod
not called on object, thisbinding setwindow
.this different python, in accessing method (
obj.mymethod
) creates bound method object.what value of
this
@ line d? why?<script type="text/javascript"> function myfun() { // line d } var obj = { mymethod : function () { eval("myfun()"); } }; obj.mymethod(); </script>
window
this 1 tricky. when evaluating eval code,
this
obj
. however, in eval code,myfun
not called on object, thisbinding setwindow
call.what value of
this
@ line e?<script type="text/javascript"> function myfun() { // line e } var obj = { somedata: "a string" }; myfun.call(obj); </script>
obj
the line
myfun.call(obj);
invoking special built-in function function.prototype.call(), accepts thisarg first argument.
Comments
Post a Comment