Author: small white gentleman reprint please indicate the source
1. this
Default behavior – Default binding rules
When a standalone function is called, the default binding rules apply. Can be regarded as the default rule when no other rule can be applied
The default binding rule points to window in non-strict mode and undefined in strict mode
Function foo() {console.log(this.a)} // We can't use let or const because the variable declared by var is used as an attribute of the window. Let and const variables do not declare var a = 2 foo() // 2Copy the code
2. this
Covert behavior of – implicit binding
When a function call has a context object, the implicit binding rule binds this in the function call to that context object
function foo() { console.log(this.a) } let obj2 = { a: 42, foo: foo } let obj1 = { a: 2, obj2: Obj1.obj2.foo () // 42Copy the code
Implicit loss (a reference call to a function, when passing in a callback function)
function foo() {
console.log(this.a)
}
function doFoo(fn) {
fn()
}
var obj = {
a: 2,
foo: foo
}
var a = 'oops, global'
doFoo(obj.foo) // oops, global
Copy the code
3. this
Behavior on the surface – show binding
By the call (..) , apply(..) , bind(..) Bind the this display to an object
function foo() {
console.log(this.a)
}
var obj = {
a: 2
}
foo.call(obj) // 2
Copy the code
4. this
thenew
The binding behavior
When a function is called with new, the following action is performed automatically
- Create a new object
- The new object will be connected by the implementation prototype chain
- When the function is called
this
Bind to this object
- If the function returns no other object, this object is automatically returned
5. this
Binding priority
New Binding > Show Binding > Implicit Binding > Default binding
Arrow functionthis
Binding rules
Inside the arrow function, the this binding is not dynamic, but lexical; in short, the arrow function’s this refers to the context object at the time the function is defined, not the context object at the time it is called
Arrow functions have no arguments of their own, but inherit from the parent layer
7. call
.apply
.bind
implementation
1. call
implementation
Function.prototype.callFn = function(context, ... args) { if (typeof this ! == 'function') { throw new TypeError(this + ' is not a function') } if (typeof context === 'undefined' || context === null) { context = window } let fnSymbol = Symbol() context[fnSymbol] = this let result = context[fnSymbol](... args) delete context[fnSymbol] return result }Copy the code
2. apply
implementation
Function.prototype.applyFn = function(context, args) { if (typeof this ! == 'function') { throw new TypeError(this + ' is not a function') } if (typeof context === 'undefined' || context === null) { context = window } let fnSymbol = Symbol() context[fnSymbol] = this let result = context[fnSymbol](... args) delete context[fnSymbol] return result }Copy the code
3. bind
implementation
Function.prototype.bindFn = function(context, ... thisArgs) { if (typeof this ! == 'function') { throw new TypeError(this + ' is not a function') } if (typeof context === 'undefined' || context === null) { context = window } let self = this return function(... args) { return self.apply(context, args.concat(thisArgs)) } }Copy the code
4. new
The implementation of the
function newFn() { let newObj = {} Constructor = [].shift.call(arguments) newObj.__proto__ = Constructor.prototype const result = Constructor.apply(newObj, arguments) return typeof result === 'object' ? result : newObj }Copy the code