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 (objin 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>windowline 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>objwhen 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>windowin example, javascript interpreter enters function code, because
myfun/obj.mymethodnot 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>windowthis 1 tricky. when evaluating eval code,
thisobj. however, in eval code,myfunnot called on object, thisbinding setwindowcall.what value of
this@ line e?<script type="text/javascript"> function myfun() { // line e } var obj = { somedata: "a string" }; myfun.call(obj); </script>objthe line
myfun.call(obj);invoking special built-in function function.prototype.call(), accepts thisarg first argument.
Comments
Post a Comment