preface
Refer to the following articles
40 more questions for this interview
First, there are several ways to bind this
-
Default binding (in non-strict mode this refers to global object, in strict mode this is bound to undefined)
-
Implicit binding (when a function references a context object, such as the way obj.foo() is called, where this in foo refers to obj)
-
Show bindings (specify this bindings directly via call() or apply(), such as foo.call(obj))
-
The new binding
-
Arrow function binding (the reference of this is determined by outer scope)
The function this points to
Execute the function immediately; this executes the window
1. Ordinary functions
This always refers to the object that last called it.
var name = 'window'
function Person (name) {
this.name = name
this.obj = {
name: 'obj'.foo1: function () {
console.log(this.name);
return function () {
console.log(this.name)
}
},
}
}
var person1 = new Person('person1')
var person2 = {name: 'person2'}
person1.obj.foo1() // The last object to call is obj, output obj
person1.obj.foo1()() // obj, window, the first () function executes the output obj, return is a function, the second () function executes immediately, this executes the window,
person1.obj.foo1.call(person2)()
person1.obj.foo1().call(person2)
Copy the code
The output
Arrow function
This is defined by the outer scope and refers to this at function definition time, not execution time.
var name = 'window'
function Person (name) {
this.name = name
this.obj = {
name: 'obj'.foo2: function () {
console.log(this.name);
return () = > {
console.log(this.name)
}
}
}
}
var person1 = new Person('person1')
var person2 = new Person('person2')
person1.obj.foo2()() // The first () executes the output obj, and the last call is obj. The second () calls the execute arrow function, whose scope is foo2, and this points to obj
person1.obj.foo2.call(person2)()
person1.obj.foo2().call(person2)
Copy the code
The output
To reassure
1.use strict
This points to in strict mode
Instead of all pointing to undefined, global this points to window, and this points to undefined inside a function
"use strict";
var a = 10;
function foo () {
console.log('this1'.this) // this1 undefined
console.log(window.a) / / 10
console.log(this.a) // This is undefined
}
console.log(window.foo) // Print the function
console.log('this2'.this) // This points to window
foo();
Copy the code
The output
2,Var and let and const
Differences in declared variables
Variables declared by let and const are not bound to the window object, so this refers to the window, which does not have this variable, and is undefined
let a = 1
const b = 2
function foo () {
console.log(this.a)
console.log(this.b)
}
foo();
console.log(window.a)
Copy the code
The execution result
Implicit loss of implicit binding
There are two situations where loss can occur
- Use another variable to alias the function
function foo () {
console.log(this.a)
};
var obj = { a: 1, foo };
var a = 2;
var foo2 = obj.foo;
obj.foo(); / / 1
foo2(); / / 2
Copy the code
Obj.foo () this refers to the object that last called this function, so it naturally points to obj output 1
Foo2 () implicitly loses the pointer, and the last call is window, so it points to window and outputs 2
- 2. The function is implicitly assigned when passed as an argument, and the callback loses the this binding
function foo () {
console.log(this.a)
}
function doFoo (fn) {
console.log(this)
fn()
}
var obj = { a: 1, foo }
obj2 = { a: 3, doFoo}
var a = 2
doFoo(obj.foo)
obj2.doFoo(obj.foo)
Copy the code
The output
- 1.
doFoo(ob.foo()
When executed,doFoo()
This points to the window, - 2,
obj.foo()
namelydoFoo
Parameters insidefn()
Implicitly missing, this refers to window
- 3,
obj2.doFoo(obj.foo)
When executed,doFoo()
This points to obj2, - 4. Inside parameters
fn()
Implicit missing, this refers to the window, so implicit missing has nothing to do with the outer this pointerfn()
Is called by window. This refers to window.
4. Timer package functions also have implicit loss problems
var obj1 = {
a: 1
}
var obj2 = {
a: 2.foo1: function () {
console.log(this.a)
},
foo2: function () {
setTimeout(function () {
console.log(this) // window
console.log(this.a) / / 3
}, 0)}}var a = 3
obj2.foo1() / / 2
obj2.foo2()
Copy the code