1. Introduction
At first, many people have a misunderstanding about this, including myself. Before I really understand the mechanism of this in Javascript, I might think this refers to itself. The this keyword is one of the most complex mechanisms in Javascript. It is a special keyword that is automatically defined in the scope of all functions. But even experienced Javascript developers have a hard time figuring out what it points to. Therefore, I can only give this a more comprehensive concept analysis, clear its call mechanism, I hope to be helpful to you.
Definition 2.
When a function is called, an active record (sometimes called the execution context) is created. This record contains information about where the function was called (call stack), how the function was called, the parameters passed in, and so on. This is an attribute of the current record that is used during function execution.
3. Code parsing
The definition of this is a little tricky, but you need to remember that this does not refer to itself, but to the scope that calls it. The following code should make sense to you.
1. Call location
function baz() {
// Current call stack: baz
console.log('baz');
bar()//bar is called in baz
}
function bar() {
// Current call stack: baz -> bar
console.log('bar');
foo()//foo is called inside a bar
}
function foo(){
// Current call stack: baz -> bar ->foo
console.log('foo');
}
baz() // baz is called globally
Copy the code
2. Binding rules
1. Default binding (independent function calls)
function foo(){
var a = 3// The variable a is not used
console.log(this.a)// This points to the window (global). Note that the Node environment has no Windows
}
var a = 2
foo() //2 instead of 3
Copy the code
How do I know that this refers to the global object? We can use a strict node where global objects cannot be used for schema binding, so here this is bound to undefined:
"use strict" // Strict mode
function foo(){
console.log(this.a)
}
var a = 2
foo()//undefined
Copy the code
2. Implicit binding (whether the calling location has a context object, or is owned or contained by an object.)
function foo(){
console.log(this.a);
}
var obj = {
a:2.foo:foo // Implicit binding
}
obj.foo() / / 2
Copy the code
The first thing to notice is how foo() is declared and how it is later added to OBj as a reference property. But whether defined directly in OBj or defined first and then added as a reference property, this function is not strictly an OBj object. However, the call location references the function using the OBJ context, so you can say that the function “owns” or “contains” the function reference when called.
One thing to note here is that only the last or upper level of the object attribute reference chain is relevant at the call location. For example:
function foo(){
console.log(this.a);
}
var obj2 = {
a:4.foo:foo // Implicit binding
}
var obj1 = {
a:2.obj2:obj2
}
obj1.foo() / / an error
obj1.obj2.foo() / / 4
Copy the code
Implicit loss: One of the most common problems with this binding is that a function that is implicitly bound loses its bound object, that is, it applies the default binding.
function foo(){
console.log(this.a);
}
var obj = {
a:2.foo:foo // Implicit binding
}
var bar = obj.foo // Function alias!
var a = 4
bar() // 4 calls global a below
Copy the code
3. Display binding (specify this binding object)
Here’s a common method in Javascript: call()
function foo(){
console.log(this.a);
}
var obj = {
a:2
}
foo() //undefined
foo().call(obj) / / 2
Copy the code
Used foo. Call (..) We can force foo’s this to be bound to obj when calling foo instead of being a global object.
One more thing: if you pass in a raw value (string, Boolean, number…) To bind to this, the original value is replaced with its object form (i.e., new String(..)). , new Boolean (..) And the new Number (..) , etc.). This is often referred to as “boxing”.