Annoying this,7 interview questions about js keywords

In JavaScript, this is the call context of the function.
The difficulty is that this has complex behavior.
In this article, I have sorted out a list of 7 interesting interview questions about this keyword.
Note: the following JavaScript fragment runs in non strict mode, also known as sloppy mode.

1: Variable vs attribute

What does the following code print on the console:

const object = {

message: 'Hello, World!',

getMessage() {

const message = 'Hello, Earth!';

return this.message;

}

};

console.log(object.getMessage()); // What will be printed?

<details>
< summary > Click to view the answer < / summary >

'Hello, World!' Is printed to the console.
object.getMessage() is a method call, so this points to object.
There is also a variable declaration const message = 'Hello, Earth!'. This variable does not affect the value of this.message.
</details>

2: Cat name

function Pet(name) {

this.name = name;

this.getName = () => this.name;

}

const cat = new Pet('Fluffy');

console.log(cat.getName()); // What will be printed?

const { getName } = cat;

console.log(getName()); // What will be printed?

<details>
< summary > Click to view the answer < / summary >

The console will print 'fluffy'   and  ' Fluffy'.
When a function calls new Pet('Fluffy ') as a constructor, this inside the constructor is equal to the constructed object.
The this.name = name code in the Pet constructor creates the name attribute on the constructed object.
This.getName = () = > this.name creates a method getName on the constructed object. And because the arrow function is used, this inside the arrow function is equal to this in the external scope - the constructor Pet.
Call cat.getName() and getName(), and the result returned is "Fluffy".
</details>

3.setTimeout and this

const object = {
  message: 'Hello, World!',
  logMessage() {
    console.log(this.message); // What will be printed?
  }
};
setTimeout(object.logMessage, 1000);

<details>
< summary > Click to view the answer < / summary >

After a delay of 1 second, undefined will print to the console.
Although the setTimeout() function uses object.logMessage as a callback, it takes object.logMessage as a regular function instead of a method.

And during regular function calls, this points to the global object, which is window in the browser environment.

This is why console.log(this.message) in the logMessage method prints undefined.

</details>

Collateral challenge: how to fix this code to 'Hello, World!' Print to console?

4. Manual method

How to call logMessage function to make it print "Hello, World!"?

const object = {

message: 'Hello, World!'

};

function logMessage() {

console.log(this.message); // "Hello, World!"

}

// Write your code here

<details>
< summary > Click to view the answer < / summary >

There are at least three methods that can call logMessage() from the object's method.

const object = {

message: 'Hello, World!'

};

function logMessage() {

console.log(this.message); // logs 'Hello, World!'

}

// Use func.call() 

logMessage.call(object);

// Use func.apply() 

logMessage.apply(object);

// Creating a bound function

const boundLogMessage = logMessage.bind(object);

boundLogMessage();

</details>

5. Arrow function

const object = {

who: 'World',

greet() {

return `Hello, ${this.who}!`;

},

farewell: () => {

return `Goodbye, ${this.who}!`;

}

};

console.log(object.greet()); // What will be printed?

console.log(object.farewell()); // What will be printed?

<details>
< summary > Click to view the answer < / summary >

'Hello, World!' And 'Goodbye, undefined!' Will be printed to the console.
When object.greet() is called, in the method greet (), because greet is a regular function, this points to object. So object.greet() returns' Hello, World! '.

However, farewell() is an arrow function, so this inside the arrow function is always equal to this outside the scope.

The external scope of farewell () is the global scope, where this is the global object. Therefore, object.farewell() actually returns "Goodyear, ${window. Who}!" and its calculation result is "Goodyear, undefined!".

</details>

  6. Confused length

What will the following code print?

var length = 4;

function callback() {

console.log(this.length); // What is logged?

}

const object = {

length: 5,

method(callback) {

callback();

}

};

object.method(callback, 1, 2);

<details>
< summary > Click to view the answer < / summary >

4 will be printed to the console.
Callback () is called as a regular function. Since this points to the global object during regular function calls, this.length in the callback() function is evaluated as window.length.

In the outermost scope, the first statement var length = 4 creates an attribute length on the global object: window.length becomes 4.

Finally, in the callback() function, this.length is calculated as window.length, so 4 is recorded to the console.
</details>

7. Call parameters

var length = 4;

function callback() {

console.log(this.length); // What is logged?

}

const object = {

length: 5,

method() {

arguments[0]();

}

};

object.method(callback, 1, 2);

<details>
< summary > Click to view the answer < / summary >

3 will be printed to the console.
obj.method(callback, 1, 2) is called with three parameters: callback, 1 and 2. Therefore, the arguments variable in method() is a class array object with the following structure:

{
0: callback,
1: 1,
2: 2,
length: 3
}

Because arguments[0] () is a call to the callback method of the arguments object, this in the callback points to arguments. Therefore, this.length in callback() is the same as arguments.length, i.e. 3.
</details>

summary

If you answered 5 or more questions correctly, you will have a good understanding of this keyword!

Otherwise, you need to review the this keyword.

Author: Dmitri Pavlutin translator: front end css and js dry goods source: Dmitri Pavlutin

Tags: Javascript Front-end this

Posted on Mon, 29 Nov 2021 03:19:41 -0500 by Texan