As I understand it this in JavaScript points to
- 2021-08-10 06:52:53
- OfStack
Preface
In JS
this
Pointing is a frequently asked question, and there are many articles about this on the Internet. This article sorts out what I understand
this
And one of the things I'm wondering about
this
Problem.
this pointing
How many
this
The point-to-point problem that almost every article will talk about, such as direct call as a function, method call as an object,
new
Operator in execution
this
Behavior. A more general statement is that,
this
Points to the object that calls the function directly. In fact, it is also very easy to understand, that is, why it is necessary
this
This keyword means that we need to operate on the object calling the function inside the function. But sometimes we encounter situations that are not like books or
mdn
Typical situations encountered in,
this
Our behavior may make us feel a little confused.
Direct call of function
When we call a declared function directly, then in non-strict mode, the internal of the function
this
Points to global objects, which is in browser environment
this
1
Object.
function f1(){
return this;
}
// In the browser:
f1() === window; // In the browser, the global object is window
// In Node Medium:
f1() === global;
This phenomenon is understandable when the function is defined in the global environment, because the function defined in the global environment is actually a property mounted on the global object, compared with the above
this
2
It can also be understood as
this
3
. But I think the behavior under the strict mode is more in line with
this
The purpose of this keyword, especially if our function may be defined and called in a non-global environment (such as another function), in which case
this
Also points to
this
1
Is not very reasonable. So in strict mode, a function directly calls its
this
It points to
this
8
If we want to get the result in non-strict mode, the method we call the function should be changed to
this
9
And if the function is defined in a non-global environment, it always returns
this
8
. I think such behavior is more logical.
'use strict'
function d () {
function e() {
console.log(this)
}
console.log(this)
}
d()
//undefined
//undefined
window.d()
//Window{}
//undefined
Use here in global mode
this
1 Just for testing, the actual use is to use strict mode locally in the function as much as possible, and strict mode under the global situation can easily lead to errors.
Function is called as a property of an object
This is also a very common scenario in code, which I think is better understood than function calls and helps us understand the behavior of this. Simply put, it is
this
It points to
this
3
The object from which the function is called. And note that this has nothing to do with where the function is defined. Let's see
this
Which is where the function is called.
// Define inside the object
var o = {
prop: 37,
f: function() {
return this.prop;
}
};
console.log(o.f()); // 37
// Define outside the object
var o = {prop: 37};
function independent() {
return this.prop;
}
o.f = independent;
console.log(o.f()); // 37
// Defined inside an object, but referenced to an external variable and executed
var o = {
prop: 37,
f: function() {
console.log(this)
return this.prop;
}
};
var prop = 100;
var m = o.f;
console.log(m());
//Window{}
//100
I gave the above paragraph
this
3
These two words are bolded to mean that when we find and call a function by nesting the properties of multiple objects, the last object closest to the function is the function
this
The direction of.
var o = {
a:10,
b:{
a:12,
fn:function(){
console.log(this.a); //12
}
}
}
o.b.fn();
var o = {
a:10,
b:{
// a:12,
fn:function(){
console.log(this.a); //undefined
}
}
}
o.b.fn();
The reason why I say this scene can help us understand is that it reflects
this
The nature of this keyword.
this
8
The function in is also a kind of object, and the active object in our execution environment only stores a reference of the function object. If this reference is stored in the attribute of an object in the active object (that is, we find the function through the attribute of an object in the active object), then when the function is executed,
this
Will point to this object, which is why the call of the multi-tier object is still the object closest to the function as
this
. Although in code our function is defined in an object, actually in memory, the object holds only a reference to the function, and the function itself is in a separate memory space. So what object do we find the function and execute the
this
Point to this object. The direct call above
this
Return
this
8
It also makes sense.
Call through prototype
Sometimes we execute common functions through prototypes, which already conforms to our above logic. If we find the function through which instance, this points to that instance.
var o = {
f: function() {
return this.a + this.b;
}
};
var p = Object.create(o);
p.a = 1;
p.b = 4;
console.log(p.f()); // 5
Arrow function
The arrow function does not have its own
this
In the arrow function
this
Is in the execution environment in which it is located
this
(
mdn
Is written in a closed lexical environment), when you encounter the arrow function
this
When you are not sure, you can imagine replacing this arrow function with
console.log(this)
The output of this console is in the arrow function
this
And the this of the arrow function is bound and does not change (sometimes it seems to change where it is located
context
Changed). Another point to note is that using
call
,
apply
,
bind
To call the arrow function, the first parameter is meaningless, that is, it cannot be changed
this
If you still need to use it, the first parameter should be passed
null
. Look
mdn
The example given by.
var globalObject = this;
var foo = (() => this);
console.log(foo() === globalObject); // true
// Then the code above
// Object as an object 1 Method calls
var obj = {foo: foo};
console.log(obj.foo() === globalObject); // true
// Try using call To set this
console.log(foo.call(obj) === globalObject); // true
// Try using bind To set this
foo = foo.bind(obj);
console.log(foo() === globalObject); // true
// Create 1 Contains bar Method's obj Object,
// bar Return 1 Functions,
// This function returns this ,
// The returned function is created as an arrow function,
// So its this Is permanently bound to its outer functions this .
// bar Can be set in the call, which in turn sets the value of the return function.
var obj = {
bar: function() {
var x = (() => this);
return x;
}
};
// As obj Object's 1 Methods to call bar , put its this Bind to obj .
// Assigns a reference to the returned function to fn .
var fn = obj.bar();
// Direct call fn Without setting this ,
// Usually ( That is, the arrow function is not used ) Default to global object
// If in strict mode; Otherwise undefined
console.log(fn() === obj); // true
// But note that if you just quote obj The method,
// Without calling it
var fn2 = obj.bar;
// Then after calling the arrow function, this Point window Because it starts from bar Inherit this .
console.log(fn2()() == window); // true
Other circumstances
There are still one situation that I think is relatively simple, so I have mentioned it once.
1. When a function is used as an event handler, its
this
Points to the element that triggered the event.
2. When code is inlined
on-event
When processing a function call, its this points to the DOM element where the listener is located, noting that only the outermost
this
Well, if there are nested functions inside, the nested function's
this
Still points to global objects in non-strict mode.
3. In the constructor
this
See the parsing and implementation of the new operator in the previous article JavaScript
4.
bind
,
this
4
And
apply
All 1 sample, function of
this
Is bound to the first parameter.
Summarize
That's what I've summed up
this
7
In
this
If there are any omissions or mistakes, please correct them.