js's understanding of this and call apply bind to change this point

About this in JavaScript

1. Function precompilation process this -> window

function foo() {
    
    
    console.log(this);
}

foo(); //全局变量

The this in the function call also points to a global variable.

Note: There are no global variables in the strict mode of ECMAScript5, where this is undefined.

2. This -> window in the global scope

console.log(this); //全局变量

The global scope uses this to point to the global variable, which is the window in the browser environment.

Note: There are no global variables in the strict mode of ECMAScript5, where this is undefined.

3. Object method call

var test = {
    
    
    foo: function () {
    
    
        console.log(this);
    }
}

test.foo(); //test对象

In object method calls, this points to the caller.

4. Constructor call

If a function or method call is preceded by the keyword new, it constitutes a constructor call. Use new to call a function, or when a constructor call occurs, the following operations will be performed automatically.

  1. Create an empty object with var this=Object.create(foo.prototype) implicitly at the top of the function body
  2. Execute this.xx = xx; add attribute methods to this
  3. Implicitly return this
 function foo(x){
    
    
  this.x = x;
  console.log(this); // foo {x: 2}
}
var f = new foo(2); 
console.log(f.x); // 2

When using new to call foo(), a new object will be constructed and bound to this in the foo() call. That is, the this of the constructor points to the object instantiated by it.

5. call apply bind changed this

function foo(a, b) {
    
    
    console.log(this);
}

var bar = {
    
    };

foo.apply(bar, [1, 2]); //bar
foo.call(1, 2); //Number对象

Using the call or apply method of Function.prototype, this inside the function will be set as the first parameter passed in. If undefined and null after call and apply, this points to window

6. Element binding events, this in the function executed after the event is triggered points to the current element

 <input type="button" value="点我">
 <script>
 document.querySelector("input").onclick = function(){
    
    
 console.log(this); //指向当前按钮
 };
 </script>

Change this to

In ECMAScript, each function contains two inherited methods: apply() and call(). The purpose of these two methods is to call the function in a specific scope. The main function is the same as bind. Change the point of this in the function body, or change the context when the function is called.

1. call and apply

apply() and call(), these two methods are used to call a function in a specific scope. The main function is the same as bind, which is used to change the direction of this in the function body, or to change the context when the function is called.

We can use this feature to implement the following code by borrowing other functions to achieve our own functions:

   function Person(name, age, sex) {
    
    
        this. name = name;
        this.age = age;
        this.sex = sex;
    }
    function Student ( name, age, sex, tel, grade) {
    
    
     // Person.call(this,name, age ,sex) ;
        Person.apply(this,[name, age ,sex]) ;
        this.tel = tel;
        this.grade = grade;
    }
    var student = new Student( 'sunny', 123, 'male', 139, 2017)
    console.log(student.name)//sunny

We can see that there is no name attribute in the original Student constructor, and our call and apply are used to dynamically change this.

Here is another common usage example: the array does not have a max method, you can use the max method on the Math object

    const arr =[1,2,3,4,5]
    const max = Math.max.apply(null,arr)
    console.log(max)//5

call

The call() method uses a specified this value and one or more parameters to call a function.

fun.call(thisArg,arg1,arg,…)

  • thisArg is the this value specified when the fun function is running (in non-strict mode, when specified as null or undefined, it will automatically point to the global object)
  • arg1.arg2... is the specified parameter list

apply

fun.apply(thisArg,[argsArray])

  • thisArg is the this value specified when the fun function is running (in non-strict mode, it will automatically point to the global object when it is specified as null or undefined)
  • argsArray is an array or array-like object, the elements in the array will be passed to the fun function as separate parameters if
  • When argsArray is nul or undefined, it means that no parameters need to be passed in.

2. bind

fun.bind(thisArg,arg1,arg2,…).

  • thisArg When the bound function is called, this parameter will be used as the this point of the original function when it is running. When using the new operator to call the binding function, this parameter is invalid.
  • arg1, arg2, …When the bound function is called, these parameters will be placed before the actual parameters and passed to the bound method. //If you bind a new this to a certain function and pass in a few variables first, you can pass in at the time of binding. After that, the parameters passed in to call the new function will be listed later.
const obj= {
    
    }
function test(..args) {
    
    
console.log(args);
const newFn = test.bind(obj, 1,2);
newFn(3,4);
// [1,2,3,4]

3. Call apply bind summary

Let's just look at the relationship between the three

//先来一个对象big吧
var big = {
    
    
    name:'BaBa',
    saying:function (age){
    
    
        console.log(this.name,'age:',age);
    }
};

//再来一个small对象
var small= {
    
    
    name:'ErZi'
};

//如果想调用big的saying方法来说出‘Erzi’:
//使用bind方法
big.saying.bind(small)(20);//打印结果为ErZi age: 20
//使用call方法
big.saying.call(small,20);//打印结果为ErZi age: 20
//使用apply方法
big.saying.apply(small,[20]);//打印结果为ErZi age: 20

Summarize the three

1. Usage scenarios

  • When a function needs to change the this point and there are fewer parameters, call can be used
  • If there are many parameters, you can organize the parameters into an array and use apply
  • If you want to generate a new function to bind an object for a long time, you can use bind

2. The same points
are used to change this point

3. Differences

  • The usage mechanism of call and apply is almost the same, the only difference is that the parameters are different. The call function is passed in one parameter, and the apply parameter
    is an array.
  • The method of passing parameters of bind is the same as that of call, but the direction of the calling function is changed and a new function is returned.
    When this function is called later, this points to the first parameter of bind binding.

Expansion: Encapsulate the bind method by yourself

//bind方法
    //1、bind方法放在函数的原型中
    //  -->fn.__proto__===fn的构造函数.prototype
    //  -->所有的函数对象的构造函数是Function
    //      -->Function 创建了Function
    //      -->Function 创建了Object 
    //      -->Function 创建了fn
    Function.prototype._bind=function(target){
    
    
        //这里的this其实fn

        //target表示新函数的内部的this的值
        
        //利用闭包创建一个内部函数,返回那个所谓的新函数
        return ()=>{
    
    
            //执行fn里面的逻辑
            this.call(target);  //this.apply(target)
        }

        // //等价于:
        // var _that=this;
        // return function(){
    
    
        //     _that.call(target);
        // }
    }

    function fn(){
    
    
        console.log(this);
    }

    var _f1=fn.bind({
    
    age:18})

Guess you like

Origin blog.csdn.net/pz1021/article/details/105144236