A lot of nonsense and a lot of questions

The beginner’s way of learning is always a problem with all kinds of dishes. If you want to call an attribute when iterating through a set of numbers with jquery, you will find that this refers to the element being iterated over instead of the external element. See the code below

var Page = function () {
    this.temp = 'P';
    this.things = [1.2.3];
    this.show = function () {
        $.each(this.things, function (index, value) {
            // This refers to each value in the array, so this. Temp fails, undefined
            console.log(this.temp + ' '+ value); }); }}var p = new Page();
p.show();
Copy the code

emmm…… That’s about it.

Some solutions

Here’s the solution I came up with, starting with the stupid one.

A stupid idea

The first thing that comes to mind is to define the external this as a variable to be used, as shown below

var Page = function () {
    this.temp = 'P';
    this.things = [1.2.3];
    this.show = function () {
        // Define a variable
        var that = this;
        $.each(this.things, function (index, value) {
            // Use the newly defined variable instead
            console.log(that.temp + ' '+ value); }); }}var p = new Page();
p.show();
Copy the code

That works, but it defines a variable, no, no, it’s too much trouble.

Another way

The arrow function’s this refers to the this value of the context in which it is located, so it should be solved, as shown below

var Page = function () {
    this.temp = 'P';
    this.things = [1.2.3];
    this.show = function () {
        // Arrow function
        $.each(this.things, (index, value) = > {
            console.log(this.temp + ' '+ value); }); }}var p = new Page();
p.show();
Copy the code

Another option is bind

As you know, bind can change the “this” in a function. The bind() method creates a new function, the bind function, that, when called, takes as this the first argument passed to the bind() method when it was created. As shown below.

var Page = function () {
    this.temp = 'P';
    this.things = [1.2.3];
    this.show = function () {
        $.each(this.things, function (index, value) {
            console.log(this.temp + ' ' + value);
        }.bind(this));
        // The external this is called to bind, so that when this is called inside the function, it refers to the external this}}var p = new Page();
p.show();
Copy the code

But the problem with this experiment is that the bind overlay doesn’t work. If you want to ask why, it is too dishes do not know.

The point after a meal of digression

Now that I’ve just said bind() for the title of this article, let’s talk about call and apply. Similar to the bind method, they also change the direction of this in the function.

Use of apply and call

On the first code

var Person = function () {
    this.name = 'li lei';
    // Define a greeting method
    this.sayHello = function () {
        console.log('Hello, I am.' + this.name); }}var Student = function () {
    this.name = 'Han Meimei';
}

var p = new Person();
var s = new Student();
p.sayHello();    // Print the result "Hello, I am Li Lei"
p.sayHello.call(s);    // Call is used to change the context of the sayHello function to s, so the print result is "hello, I am Han Meimei"
p.sayHello.apply(s);    // The sayHello function's context is changed by apply, so the print result is "hello, I am Han Meimei"
Copy the code

As stated in the code and comments above, Student does not define sayHello, so when we want to use sayHello on s, we have to borrow it from P, because P has it. Here call and apply change the context of the p.sayhello method by referring this to the s object, so when sayHello is printed to this.name, it becomes’ Han Meimei ‘.

Difference between Apply and call

So again, in the above code it looks like call and apply are the same, so why have two? Take a look at the code below

function add(a, b, c) {
    return (a + b + c);
}
function callTest(a, b, c) {
    return add.call(this, a, b, c);    // The parameters must correspond to each other
}
function applyTest(a, b, c) {
    return add.apply(this, [a, b, c]);    // Pass the parameter as an array
}

console.log(callTest(1.2.3));
console.log(applyTest(1.2.3));
Copy the code

As you can see, call requires parameters to be passed in order, while apply puts parameters in an array. So to apply conditions, you can use call when you know the number explicitly, and apply when you’re not sure, and then push the parameters into the array. Arguments can also be iterated internally through the pseudo-array arguments if the number of arguments is uncertain.

Compare that with BIND

Now that we’ve talked about the difference between call and apply, what’s the difference between call and bind? As mentioned earlier, the bind method creates a binding function that only takes effect when it is called. Call and apply take effect immediately, while bind takes effect after it is called. Here is a piece of code to verify

var test1 = {
    temp: 5
}
var test2 = {
    show: function () {
        console.log(this.temp);
    }
}
test2.show.call(test1);
test2.show.apply(test1);
test2.show.bind(test1)();    // It is obvious that this function is called actively
Copy the code

A summary of

So just to conclude

1. All three functions change the context of the function, that is, the function “this” refers to, similar to the title of “your function”.

2. The first argument of each of the three is the body of the borrowed function, and subsequent arguments can be passed in;

3. Bind waits for the call, while the other two call immediately.