preamble
Recently in the look back JavaScript interview questions, this pointing problem is into the pit front-end must understand the knowledge points, now ushered in the era of ES6 +, because of the emergence of the arrow function, so I feel the need to this problem sorted out, so just to summarize the problem of this pointing in JavaScript.
What is JavaScript
Before you can understand the problem with this pointing, you first have to understand what JavaScript is.
JavaScript ("JS") is a function-first, lightweight, interpreted or just-in-time compiled programming language.JavaScript is a dynamic scripting language based on prototypical programming, multi-paradigm, and supports object-oriented, imperative, declarative, and functional programming paradigms, as well as advanced features such as functional programming, closures, prototype-based inheritance, and other advanced features.
What is this
In object-oriented languages, this is a reference to the current object.
But this is not fixed in JavaScript; it changes depending on the environment in which it is executed.
In a method, this indicates the object to which the method belongs.
If used alone, this represents the global object.
In a function, this represents the global object.
In functions, in strict mode, this is undefined.
In an event, this represents the element that receives the event.
Methods like call() and apply() can change the point of this to refer to any object.
So what this points to depends entirely on how the function is called.
Pointing to this
Next I will go through the following example diagrams and examples in (non-strict mode) to understand where this points.
1. Do not use the new keyword, use dot call.
var obj = {
name: 'bugs',
obj2: {
fn: function () {
(); //bug2
}
}
}
//Here the fn function in obj2 is called via obj.(), where this points to dot (.) in the fn function. The previous object is obj2, and the name in obj2 is bug2.
obj.();
2. Called using the new keyword.
function fn() {
= function fn() { function fn() { function fn() { function fn()
}
// Here an instance is created with the new keyword, and this points to the instance fn.
var obj = new fn();
// The structure of obj is {x:1}, so = 1.
// 1
Speaking of the new keyword just derived to see another key point, if I use new to create an instance of the object, this time the instance of the object has a return value?
Normally there should be no explicit return values.
But if when return returns an object, then that object will be returned.
But if when return returns a non-object type (e.g., number, string, etc.), then it does not affect the creation of the object by the new keyword.
Here are a few examples to verify this:
①return empty object
function fn()
{
= 'bug'.
// This returns an object.
return {}.
}
var obj = new fn(); //This time, because return is an object, the structure of obj is the empty object {}.
//This is because the return is an object, so the structure of obj is the empty object {}, which is why it is undefined.
(); //undefined
②return a non-null object
function fn()
{
= 'bug'.
// here return an object
return {name:'bug2'};
}
var obj = new fn(); //This is where we return a non-null object.
// At this point, since return returns a non-null object, the structure of obj at this point is the returned non-null object {name:'bug2'}, so it's bug2
(); //bug2
③Return number
function fn()
{
= 'bug'.
// This returns a number.
return 11; }
}
var obj = new fn();
//This time, because return returns a number, the instance object returned here is unaffected, and the structure is {name:'bug'}, so it's bug
(); //bug
④Return string
function fn()
{
= 'bug'.
// Here the return is a string.
return 'xxxxx';
}
var obj = new fn(); //This time, because return is a string, the returned instance object is unaffected.
//This time, because return returns a string, the instance object returned is unaffected, and the structure is {name:'bug'}, so it's bug
(); //bug
Since we're now in the era of Es6+, we have to talk about this pointing to arrow functions
1. What is an arrow function
Arrow functions are a new way of defining functions in ECMAScript 6, also known as Lambda functions. It uses the arrow (=>) notation to replace the traditional function keyword, thus defining the function more concisely and making the code more concise and readable.
Arrow functions have the following characteristics:
① Concise syntax: the syntax of arrow function expressions is more concise than that of normal functions. Using the arrow (=>) notation to define a function allows you to omit unnecessary syntactic elements such as the function keyword, curly braces, and parentheses around the parameter list (if there is only one parameter).
② this binding: an arrow function does not bind its own this, it captures the value of this in the context in which it was defined, which makes the pointing of this more explicit and predictable when using arrow functions in callback functions or nested functions.
③ No arguments object: Arrow functions do not have their own arguments object, which means that they do not have access to the special attribute arguments of traditional functions.
④ Cannot be used as constructors: arrow functions cannot be used as constructors, i.e., they cannot be used for class instantiation.
2. Arrow function's this pointer
Because an arrow function is not bound to its own this, it captures the this value of the context in which it was defined. So the simple fact is that arrow functions don't have their own this.
Let's take a quick look with an example.
①Normal function function
const obj={
mythis: function(){
(this) // points to the higher-level object obj
}
}
() //returns the obj object
②Arrow Functions
const obj={
mythis: ()=>{
(this) // since the arrow function doesn't have its own this, it points to the window
}
}
() // returns the window
Oh here's another pitfall, as mentioned earlier, this points to something that depends entirely on how the function is called.
What do you see again in the final return of this question?
const obj={
mythis: function(){
(this)
}
}
var a =
a()
Click for Answers and Explanations
//Is it possible that some of you are thinking that this is a function, so the return is still obj, which is the higher level object of mythis?
//No, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, no.
//The reason why the above example (1) returns obj is because it is called directly (), and this points to the higher level object of mythis.
//but in this example, a is directly assigned to a by subtracting mythis, at this point, a becomes an ordinary function reference, which is just a copy of obj, and does not have the context information of obj.
//So when a is called as a normal function (not as a method call on an object), in non-strict mode, this in JavaScript points to the global object window by default.
const obj={
mythis: function(){
(this)
}
}
var a =
a() //window
Of course, while the pointing of this is different depending on how the call is made, there are other ways to force the pointing of this to be changed! That's using call, apply, bind.
What is call, apply, bind and what is the difference?
1. What is a call?
The call method can take two arguments. The first argument is the point of this, which points to xxx, and the second argument is a list of arguments. When the first argument is null or undefined, this points to the window by default.
function fn(... .args) {
(this, args); }
}
let obj = {
name: "bug"
}
// Point this of fn to obj and pass in a list of arguments 1, 2
(obj, 1, 2); //{name:'bug'} , [1,2]
//This in fn points to window.
fn(1, 2) //window , [1,2]
//when first argument is null, this points to window
(null,[1,2]);//window , [1,2]
//when first argument is undefined, this points to window
(undefined,[1,2]);//window , [1,2]
2. What is apply?
The apply method can take two arguments. The first argument is the point of this, which points to xxx, and the second argument is an array of arguments. When the first parameter is null or undefined, this points to window by default.
function fn(... .args) {
(this, args); }
}
let obj = {
name: "bug"
}
//point this of fn to obj and pass in the parameter array [[1,2]]
(obj, [1,2]); //{name:'bug'} , [[1,2]]
//The this in fn points to window
fn([1,2]) //window , [[1,2]]
//when first argument is null, this points to window
(null,[1,2]);//window , [[1,2]]
//when the first argument is undefined, this points to window
(undefined,[1,2]);//window , [[1,2]]
3. What is bind?
The bind method is very similar to call and apply in that the first parameter is also a pointer to this, and the second parameter is passed a list of arguments, however! The second argument is also a list of arguments, but! And it doesn't execute immediately after changing this, it returns a function that has permanently changed this.
function fn(... .args) {
(this, args); }
}
let obj = {
name: "bug"
}
const bindFn = (obj); //this becomes obj, and is not executed immediately
bindFn(1, 2) //has to be called to be executed, and is passed a list of arguments 1,2, eventually this points to obj {name:'bug'}
fn(1, 2) //this executes window
What is the difference between, apply, bind?
① All three can change the function's this object to point to the
② the first parameter of all three is the object this points to, if there is no such parameter or the parameter is undefined or null, then the default is to point to the global window
All three can pass parameters, but apply is an array, while call is a list of parameters, and apply and call are one-time parameter passes, while bind can be divided into multiple passes bind is a function that returns to the function after binding this, and apply and call are executed immediately.
summarize
Simply put, this is not fixed, it changes as the execution environment changes, and how it changes depends entirely on how the function is called.
Arrow functions do not have a this of their own; the arrow function this that is a method points to the current context.
I am just graduated more than a year of small rookie, the above for personal learning to organize the content, the level is limited, if there is any error, look forward to your garden friends do not begrudge advice! If you think it's good, please click recommend and attention! Thank you~๑-́₃-̀๑ [flower][flower][flower][flower].