preface

In the global context, this is undefined by strict default, and in non-strict mode, this is window. The this of a block-level scope is inherited from the context of this. In the private context of a function, the this case varies.

Note that this is not the execution context, EC is the execution context, and this is the execution body.

1. Element events

Bind a method to an element’s event behavior, the event fires, the method executes, and this in the method is usually the current element itself.

// DOM0
 btn.onclick = function anonymous() {
    console.log(this); // This refers to the element province
 }
 // DOM2
 btn.addEventListener('click'.function anonymous() {
     console.log(this); // This refers to the element province
 }, false);
 / / DOM2 - ie
 btn.attachEvent('onclick'.function anonymous() {  
    // <= IE8
     console.log(this); // this -> window special case
 })
Copy the code

2. Common function execution

Normal function execution, this in it depends on whether the execution method has a “dot” in front of it, “dot”, “dot” in front of it, this is whoever, no “dot”, non-strict mode this is window, strict mode undefined.

3. Constructor execution

The constructor executes, and this executes an instance of the current class.

function Func() {
    this.name = "F";
    console.log(this); //=> THIS in the constructor body is an instance of the current class in constructor execution mode, and this. XXX=XXX is a private property set for the current instance
}
Func.prototype.getNum = function getNum() {
    // THIS is not always an instance of a prototypical method
    console.log(this);
};
let f = new Func;
f.getNum();
f.__proto__.getNum();
Func.prototype.getNum(); 
Copy the code

Arrow function

Arrow functions have no this of their own; all this used is contextual this.

  • Arrow functions don’t have this
  • Arrow functions have no prototype
  • Arrow functions have no constructor
  • Arrow functions cannot be executed by new
  • Arrow functions don’t have arguments. If you want to use argument sets, you can only use… The args.

Ordinary functions execute:

  • Forming private Context (and AO)
    • Initialize the scope chain
    • Initialize THIS
    • To initialize the ARGUMENTS
    • Parameter value
    • Variable ascension
    • Code execution

The arrow function executes:

  • Forming private Context (and AO)
    • Parameter value
    • Code execution
    • When code executes, it encounters this and looks for this in the parent context.
let obj = {
    i: 0.// func:function(){}
    func() {
        // THIS:OBJ
        let _this = this;
        setTimeout(function () {
            // THIS:WINDOW callback function THIS is usually WINDOW (but there are special cases)
            _this.i++;
            console.log(_this);
        }, 1000); }}; obj.func();Copy the code

5. call/apply/bind

call/apply

- The first argument is to change the reference of this. In non-strict mode, null/undefined refers to window. - The only difference between call and apply is that the parameters are passed differently. The second parameter of apply is an array, and the parameters of call are passed one by one. - Call performs better than Apply (especially if more than three arguments are passed to the function)Copy the code

bind

-call /apply changes this and executes the function at the same time, but bind does not execute the function immediately. It changes this and passes some information beforehand.Copy the code

The call/apply/bind method is a call/apply/bind method. It is a call/apply/bind method. It is a call/apply/bind method.

Apply source code – Handwritten apply source code

~ (function(proto){
	function apply(content, args) {
  	if (content === undefined || contetn === null) {
    	content = window;
    } else {
    	content = Object(content);
    }
    content.$fn = this;
    varres = content.$fn(... args);delete content.$fn;
    returnres; } proto.apply = apply; }) (Function.prototype)
Copy the code

Call source code – Handwritten Call source code

~ (function(proto){
	function call(content, args) {
  	if (content === undefined || contetn === null) {
    	content = window;
    } else {
    	content = Object(content);
    }
    content.$fn = this;
    varres = content.$fn(... args);delete content.$fn;
    returnres; } proto.call = call; }) (Function.prototype)
Copy the code

Bind source code – Handwritten BIND source code

~ (function(proto) {
    function bind(content) {
        if(content === undefined || content === null) {
            content = window;
        }
        // Get the collection of arguments
        var args = [].slice.call(arguments.1);
        // The last function to execute
        var _this = this;
        return function anonymous() {
            var amArgs = [].slice.call(arguments.0); _this.apply(content, args.concat(amArgs)); } } proto.bind = bind; }) (Function.prototype); ~ (function(proto) {
    function bind(content = window. args) {
        if (content === null) {
            content = window;
        }
        return (. amArgs) = > {
            // The performance of apply with more than three parameters is not as good as that of Call
            this.call(content, ... args.content(amArgs)); } } proto.bind = bind; }) (Function.prototype);
Copy the code