JS this

Excerpted from: http://www.imooc.com/article/1758
Original author: PHPBird



When it comes to this, you have to mention function. I believe that students who have read other similar articles also know that it is precisely because the objects that call the function are different. It caused this to point to different. So I used to remember the this corresponding to each case of calling a function, because the cases are limited and rare, so of course this is feasible - for smart people. So I had to think of other ways to make me remember.
So first of all we need to make clear one thing is: function is also an object
At we also need to make clear one thing is: function is executed in a specific context. So what is context? For example, if you want to console.log(a), the execution of the function cannot be supported without a, so in a sense, a is part of the context. When the function executes, it also needs some additional information to support its operation.
Since function is an object, there will be methods. The core method in function is the call method, which is also the most critical method to understand this, so we will start from here.
call method
Let's take a look at how to use the call method first :
    function say(content) {
        console.log("From " + this + ": Hello "+ content);
    }
    say.call("Bob", "World"); / /==> From Bob: Hello World
Next, carefully analyze the usage of call:
Step1: Use the second to last parameters as the parameters to be passed in
when the function is executed Step2: Point this to the first parameter when the function is executed
Step3: Execute the function in the above special context In the
above example, we call method, let this point to "Bob" when the say function is executed, and then pass "World" as a parameter, so the output result is predictable.
js will complete the above steps by default when executing a function. You can understand calling a function directly as a kind of syntactic sugar. For
example
    function say(word) {
       console.log(world);
    }
    say("Hello world");

    say.call( window, "Hello world"); The
above can consider say("Hello world") as a syntactic sugar for say.call(window,"Hello world").
This conclusion is very critical,
so every time you see functionName(xxx) in the future, you need to replace it with functionName.call(window, xxxx), which is very important for you to understand what this points to. However, there are exceptions. In ES5's strict mode, the first parameter of call is not window but undefined. For the following examples I'm assuming always not in strictmode, but you need to keep in mind that strictmode is a little different.
For anonymous functions, the above conclusion is also true
    (function(name) {
        //
    })("aa");
    // Equivalent to
    (function(name) {
        //
    }).call(window, "aa");
The function is called as a method of the object. Look
directly the code:
    var person = {
        name : "caibirdme",
        run : function(time) {
            console.log(this.name + "has been running for over "+ time+ " minutes");
        }
    };
    person.run(30); //== > caibirdme has been running for over 30 minutes
    //equivalent to
    person.run.call(person, 30); // the same
you will find that the first parameter of call here is person instead of window.
When you understand these two points, subconsciously translate the function call into the form of foo.call(), and specify the first parameter of call, then basically the problem of this will be difficult for you.
Let's take a few examples
. Example 1:
function hello(thing) { 
  console.log(this + " says hello " + thing);
}

person = { name: "caibirdme" } 
person.hello = hello;

person.hello("world") // 相当于执行 person.hello.call(person, "world")
//{name:"caibirdme"} says hello world

hello("world") // 相当于执行 hello.call(window, "world")
//[object DOMWindow] says hello world
例二:
var obj = {
    x: 20,
    f: function(){ console.log(this.x); }
};

obj.f(); // obj.f.call(obj)
//==> 20

obj.innerobj = {
    x: 30,
    f: function(){ console.log(this.x); }
}

obj.innerobj.f(); // obj.innerobj.f.call(obj.innerobj)
// ==> 30
Example 3:
var x = 10;
var obj = {
    x: 20,
    f: function(){
        console.log(this.x); //this equals obj
                // ==> 20
        var foo = function(){ console.log(this.x); }
        foo(); // foo.call(window)
                //this is specified as window in foo, so ==> 10
    }
};

obj.f() ; // obj.f.call(obj)
// ==> 20 10
Example 3 leads to a very common question, what if I want foo to output 20? A little trick is needed at this time
Example 4:
var x = 10;
var obj = {
    x: 20,
    f: function(){
        console.log(this.x);
        var that = this; //Use that to keep the current this of the function execution context
        var foo = function(){ console.log(that.x); } //this in the foo function still points to window, but we use that to get obj
        foo(); // foo.call(window)
    }
} ;

obj.f(); obj.f.call(obj)
// ==> 20 20
Here's a slightly more difficult (but it's not at all difficult to use call substitution)
Example 5:
var x = 10;
var obj = {
    x: 20,
    f: function(){ console.log(this.x); }
};

obj.f(); // obj.f.call(obj)
// ==> 20

var fOut = obj.f;
fOut(); // fOut.call(window)
//==> 10

var obj2 = {
    x: 30,
    f: obj.f
}

obj2.f(); // obj2.f.call (obj2)
//==> 30
Example 5 The reason why some classmates may make mistakes is that it is not clear what I said above:
This is only confirmed during execution.
He may think that the function obj.f is defined in obj, then this should point to obj. If you still think so after reading this article, I will feel that my level of expression is too failed...
for constructors Let's
look at a piece of code:
    func person(name) {
        this.name = name;
    }
    var caibirdme = new person("deen");
    // caibirdme.name == deen As
I said above, the function can also be replaced by the call method when it is used as a constructor, so how to replace it here?
Here you need to be clear again:
new constrcut() is a syntactic sugar for creating objects.
It is equivalent to
    function person(name) {
       this.name = name;
    }
    var foo = new person("deen");
    // by new creates an object
    //new is a syntactic sugar, new person is equivalent to
    var bar = (function(name) {
        var _newObj = {
            constructor : person,
            __proto__ : person.prototype,
        };
        _newObj.constructor(name); // _newObj.constructor.call(_newObj, name)
        return _newObj;
    })();
So you can see...why this points to new when new object?
Through my article, I hope to learn to understand who this refers to in the runtime context by replacing a function call with the form of funcName.call. In summary, the following two equivalent variants are:
foo() ---> foo.call(window)
obj.foo() --> obj.foo.call(obj)


Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326802722&siteId=291194637
js