Interview: this keyword

Posted by cyanblue on Sat, 26 Feb 2022 09:14:49 +0100

preface

this topic is an unavoidable difficulty in study, work and interview.

Let's start with a topic:

var name = "Xiao Hong";
function a() {
    var name = "Xiaobai";
    console.log(this.name);
}
function d(i) {
    return i();
}
var b = {
    name: "Xiao Huang",
    detail: function() {
        console.log(this.name);
    },
    show: function() {
        return function() {
            console.log(this.name);
        }
    }
}
var c = b.detail;
b.a = a;
var e = b.show();
a();
c();
b.a();
d(b.detail);
e();

First do it yourself, and then put this code into the console to output the results and check the answers.

If there is something wrong, let me tell you a story and take you to sort out the test sites for this keyword binding.

Default binding

Xiao Ming is a big Bragger. Whenever someone asks him if he has a girlfriend, he sees a girl and says it's his girlfriend.

It is not clear which one is his. His girlfriend here is in the overall scope. It seems that girls all over the world belong to him.

For example, the following code:

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

Define a girl function, directly output this, and call this function in the global environment. When viewing the console, you can see that the result output is Window.

Implicit binding

In the past few years, someone asked Xiaoming's girlfriend again. At this time, Xiaoming really had a girlfriend and introduced the specific name, height, weight and other information.

This means that the attribute values in an object are explicit. For example, the following code:

var girl = {
    name: "Xiao Hong",
    height: 170,
    weight: 55,
    detail: function() {
        console.log(`full name: ${this.name}`);
        console.log(`Height: ${this.height}`);
        console.log(`Weight: ${this.weight}`);
    }
}
girl.detail();

Create a girl object with name, height, weight and a function, that is, the method of the girl object, which outputs Xiaohong's information. Implicit binding occurs whenever this method is called. The call here is the method in the girl object, and this in the output will be bound to the girl object.

Hard binding

After two years, Xiao Ming became very distracted and had three girlfriends at the same time. In addition to the original Xiao Hong, Xiao Bai and Xiao Huang. But Xiao Ming doesn't want to introduce Xiao Hong to others. He just wants to introduce Xiao Bai and Xiao Huang.

For example, the following code:

var girlName = {
    name: "Xiao Hong",
    sayName: function() {
        console.log(`My girlfriend is ${this.name}`);
    }
}
var mistress_one = {
    name: "Xiaobai"
}
var mistress_two = {
    name: "Xiao Huang"
}
girlName.sayName.call(mistress_one);
girlName.sayName.call(mistress_two);

Create a girlName object with a method to output the name. Then create two objects, record their names respectively, and finally call the methods of the objects respectively with call.

When it comes to call, we have to mention apply. Finally, the output is changed to apply, and the output result is the same.

girlName.sayName.apply(mistress_one);
girlName.sayName.apply(mistress_two);

apply and call

In JS, each Function object has an apply() method and a call() method.

apply

Call a method of an object to replace the current object with another object.

Syntax:

function.apply(thisObj[, argArray]);

call

Call a method of an object to replace the current object with another object.

Syntax:

function.call(thisObj[, arg1[, arg2[, [,...argN]]]]);

From the above, we can see their similarities and differences. The same thing is their definitions, that is, their functions are the same. The difference is that their usage syntax is different, specifically the form of the passed in parameter list is different.

The most common example is function inheritance:

function Animal(name) {
    this.name = name;
    this.show = function() {
        console.log(this.name);
    }
}
function Cat(name) {
    Animal.apply(this, [name]);
    // animal.call(this, name);
}
var myCat = new Cat("one day");
myCat.show();

There is also a wonderful use of apply to realize the combination of two arrays.

var a = [1,2,3];
var b = [4,5,6];
Array.prototype.push.apply(a, b);

The output result is the length of an array, but print a to see that a has been modified to the combined value. A calls the push method. The parameter is to convert the array into a collection of parameter lists through apply.

You can try the result of call here.

Constructor binding

Over the past period of time, Xiao Ming repented and told Xiao Hong about his behavior of stepping on three boats and begged for forgiveness. Unexpectedly, Xiao Hong forgave him, and the two entered the marriage and achieved good results.

For example, the following code:

function Lover(name) {
    this.name = name;
    this.sayName = function() {
        console.log(`my wife is ${this.name}`)
    }
}
var name = "Xiaobai";
var hostess = new Lover("Xiao Hong");
hostess.sayName();

Create a constructor and instantiate the object with the variable name Xiaohong. At this time, this will be bound with the instantiated new object Xiaohong. Even if the variable name Xiaobai with the same name appears, it will not have an impact. Check the output result is still Xiaohong.

summary

This occurs because the function appears. The function will automatically obtain this when calling. No matter where the function declaration is, this can dynamically point to the actual calling object.

In addition to the above four binding rules, it is more important to understand that this reference is the environment object for function execution, that is, which object actually executes this and what is the current execution environment of the object.

Topics: Javascript Front-end Interview