Difference between this and self in JavaScript

后端 未结 5 1375
醉酒成梦
醉酒成梦 2020-11-28 02:59

Everyone is aware of this in javascript, but there are also instances of self encountered in the wild, such as here

So, what is the differe

5条回答
  •  南笙
    南笙 (楼主)
    2020-11-28 03:30

    The reference to ECMA 5 needs clarifying.

    I assume it means ECMA-262 Edition 5. It should be noted that ECMA-262 (a.k.a. ECMAScript or, less accurately, Javascript) is a general scripting language which has been implemented in Internet Browsers. From the Edition 5.1 standard:

    The following steps are performed when control enters the execution context for function code contained in function object F, a caller provided thisArg, and a caller provided argumentsList:

    1. If the function code is strict code, set the ThisBinding to thisArg.
    2. Else if thisArg is null or undefined, set the ThisBinding to the global object.
    3. Else if Type(thisArg) is not Object, set the ThisBinding to ToObject(thisArg).
    4. Else set the ThisBinding to thisArg
    5. ... (not about "this")

    The term "global object" refers to whatever object is at the top of the scope chain. For browsers this would be the "window" object but this is an implementation choice (Windows Script Host has an invisible global object but no strict mode so unqualified references access its properties and there is no global "self"). Also, "strict mode" must be explicitly enabled otherwise it is not active (section 14.1 of the standard). As such, an undefined "this" would still resolve to the global object (window) in "ECMA 5" with strict mode not active.

    So the answer to the question is:

    "this" always refers to the object invoking the function. If the function was not invoked by an object (i.e. not a method call) then "this" (as passed to the function) is "undefined". However, if NOT using strict mode then an undefined "this" is set to the global object (rule 2 above).

    "self" has no special syntactic meaning, it is just an identifier. Browsers tend to define window.self (just a property of the global window object) = window. This results in unqualified references to "self" being the same as "window" UNLESS "self" has been redefined within an enclosing scope (such as by "var self = this;" above. Good luck redefining "this".)

    So the full explanation of the example above is:

    outer func:  this.foo = bar
    // "this" refers to the invoking object "myObject"
    outer func:  self.foo = bar
    // "self" resolves to the variable in the local scope which has been set to "this" so it is also "myObject"
    inner func:  this.foo = undefined
    // "this" refers to the invoking object (none) and so is replaced by the global object (strict mode must be off). "window" has no foo property so its "value" is undefined.
    inner func:  self.foo = bar
    // self resolves to the variable in the enclosing scope which is still "myObject"
    

    An interesting variation of the example creates a closure by returning a reference to the inner function.

    var myObject = {
     foo: "bar",
     func: function() {
        var self = this;
        console.log("outer func:  this.foo = " + this.foo);
        console.log("outer func:  self.foo = " + self.foo);
        return function() {
            console.log("inner func:  this.foo = " + this.foo);
            console.log("inner func:  self.foo = " + self.foo);
        };
      }
    };
    var yourObject = {
     foo: "blat",
     func: myObject.func() // function call not function object
    };
    console.log("----");
    yourObject.func();
    

    Producing

    outer func:  this.foo = bar
    outer func:  self.foo = bar
    ----
    inner func:  this.foo = blat
    inner func:  self.foo = bar
    

    Note how the inner function is not called until invoked by yourObject. So this.foo is now yourObject.foo but self still resolves to the variable in the enclosing scope which, at the time the inner function object was returned, was (and in the resulting closure still is) myObject. So, within the inner function, "this" refers to the object calling the inner function while "self" refers to the object which called the outer function to create the reference to the inner function.

    To summarize the summary of the summary, "this" is defined by the language standard, "self" is defined by whoever defines it (runtime implementer or end programmer).

提交回复
热议问题