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:

  1. 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).

  2. 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)(...) or var 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.

  3. entering function code

    this occurs when calling function. if function called on object, such in obj.mymethod() or equivalent obj["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.

  1. what value of this @ line a? why?

    <script type="text/javascript"> if (true) {     // line } </script> 

    window

    line evaluated in initial global execution context.

  2. 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.

  3. 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 set window.

    this different python, in accessing method (obj.mymethod) creates bound method object.

  4. 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 set window call.

  5. 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

Popular posts from this blog

javascript - RequestAnimationFrame not working when exiting fullscreen switching space on Safari -

Python ctypes access violation with const pointer arguments -