springboot actual e-commerce project mall4j (https://gitee.com/gz-yami/mall4j)
this binding in JavaScript
In daily development, we often use a keyword in JavaScript: this. In common programming languages, almost all have this keyword, but this in JavaScript and this in common languages are not very common. In the same way, in common programming languages (java, c++, etc.), this usually only appears in the method of the class, and this points to the object it is currently called, but in JavaScript, this is more flexible, whether it is Where it appears is what it represents.
this global pointer
This question is very easy to answer. In the browser, this points to the global object window
console.log(this) // window 对象
var name = "hhf"
console.log(this.name) // hhf
console.log(window.name) // hhf
However, in development, this is rarely used directly in the global role, usually in functions
What does this point to?
Below we pass a piece of code. In the code, we define a function and call it in three different ways, which produce different results
function foo() {
console.log(this)
}
foo() // window对象
const obj = {
name: "hhf",
foo: foo
}
obj.foo() // obj1
const obj2 = {}
foo.call(obj2) // obj2
From the results of running the above code we get:
1. When a function is called, JavaScript will bind a value to this by default; 2. The binding of this has nothing to do with the location of the definition (where it is written); 3. The binding of this is related to the calling method and the calling location. ; 4.this is bound at runtime
In JavaScript, this has four binding rules, namely: 1. Default binding 2. Implicit binding 3. Explicit binding 4. New binding
Next, we will study these four binding rules respectively.
default binding
The default binding is usually when the independent function is called. We can understand that the independent function call is not bound to an object for calling. The default binding points to the window in the browser, when it is in strict mode ( use strict), it points to undefined
// 案例一
function foo() {
console.log(this)
}
foo() // window对象
// 案例二
function foo(fn) {
fn()
}
const obj = {
name: "hhf",
bar: function() {
console.log(this)
}
}
foo(obj.bar) // window
show binding
Explicit binding is usually a call to it by an object. In layman's terms: whoever calls it points to whom
function foo() {
console.log(this.name);
}
const obj = {
name: "hhf",
bar: foo
}
obj.bar() // hhf
Another case of implicit binding:
When there are multiple layers of objects nested to call a function, for example 对象.对象.函数
, this points to the last layer of objects.
function foo() {
console.log(this.name);
}
const person = {
name: "person"
}
person.foo = foo
const obj = {
name: "hhf",
bar: foo,
person: person
}
obj.person.foo() // person
explicit binding
In JavaScript, all functions can use the three methods of call, apply, and bind to bind the this of the function. The different ways of use are: call and apply call it when the function is called, and bind will return a new function.
Display binding uses: anti-shake, throttling, etc.
Use of call function
The call() method calls a function with a specified this value and one or more arguments given separately. The parameters it receives are: the first is the bound this, followed by the parameters of the called function. The specific usage is as follows
// 基本使用
function foo() {
console.log(this.name);
}
const obj = {
name: "hhf"
}
foo.call(obj) // hhf
// 传入参数
function foo(n, m) {
console.log(this.name);
console.log(n, m)
}
const obj = {
name: "hhf"
}
foo.call(obj, "n", "m") // hhf n m
Use of apply function
The syntax and function of the apply method are similar to those of the call() method, except that the call() method accepts a parameter list, while the apply() method accepts an array containing multiple parameters. The specific use method is as follows
function foo(n, m) {
console.log(this.name);
console.log(n, m)
}
const obj = {
name: "hhf"
}
foo.call(obj, ["n", "m"]) // hhf, n m
Use of bind function
The bind function accepts the same parameters as the call function, but it returns a new function whose this will point to the incoming object
function foo(n, m) {
console.log(this.name);
console.log(n, m)
}
const obj = {
name: "hhf"
}
const newFoo = foo.bind(obj, "n", "m")
newFoo() // hhf n m
new binding
new is a keyword in JavaScript. When the function is called by the new operation, the following operations will be performed: 1. A new object will be created inside the function 2. The prototype of the created object ( proto ) will point to the prototype of the function 3. All The created object will be bound to the this of the function 4. If the function has no other return value, the object will be returned by default
function Persion() {
console.log(this)
}
new Persion(); // Persion {}
rule priority
We have learned four binding rules above, so we may think, if a function uses multiple binding rules when calling, who has the highest priority? The results are as follows 1. The priority of the default rule is the lowest p. There is no doubt that the priority of the default rule is the lowest, because when there are other rules, this will be bound by other rules. 2. The display binding priority is higher than implicit binding
function foo() {
console.log(this.name)
}
const obj1 = {
name: 'obj1',
foo: foo
}
const obj2 = {
name: 'obj2',
}
obj1.foo.call(obj2) // obj2
3.new binding takes precedence over implicit binding
function foo() {
console.log(this)
}
const obj1 = {
name: 'obj1',
foo: foo
}
const obj2 = {
name: 'obj2',
}
new obj1.foo() // foo {}
4. The priority of new binding is higher than that of bind new binding and call and apply are not allowed to be used at the same time, so there is no one whose priority is higher. new binding can be used with bind, and new binding has higher priority p code test
function foo() {
console.log(this)
}
const obj1 = {
name: 'obj1',
foo: foo
}
const newFoo = foo.bind(obj1)
new newFoo() // foo {}
the this of the arrow function
Arrow functions are a new way of writing functions in ES6, but arrow functions are not bound to this. When this is used in an arrow function, it will be found on the Internet along with its scope, and the nearest scope will be used. this to use
// 使用普通函数
const obj1 = {
name: 'obj1',
foo: function() {
console.log(this)
}
}
obj1.foo() // obj1
// 使用箭头函数
const obj1 = {
name: 'obj1',
foo: ()=> {
console.log(this)
}
}
obj1.foo() // window foo的上层作用域为window
// setTimeout所传入的函数如果是普通函数,那么它绑定的是全局对象window,如果传入的是一个箭头函数,那么它的this执行是它的上层作用域的this指向
const obj1 = {
name: 'obj1',
bar: function() {
setTimeout(()=> {
console.log(this)
})
}
}
obj1.bar() // obj1
Let's do a little exercise on what we just learned through a question.
var name = "window"
function Person(name) {
this.name = name
this.obj = {
name: "obj",
foo1: function() {
return function() {
console.log(this.name)
}
},
foo2: function() {
return ()=>{
console.log(this.name)
}
}
}
}
var person1 = new Person("person1")
var person2 = new Person("person2")
person1.obj.foo1()()
person1.obj.foo1.call(person2)()
person1.obj.foo1().call(person2)
person1.obj.foo2()()
person1.obj.foo2.call(person2)()
person1.obj.foo2().call(person2)
The output is
/*
window
window
person2
obj
person2
obj
*/
springboot actual e-commerce project mall4j (https://gitee.com/gz-yami/mall4j)