springboot 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, there is almost this keyword, but this in JavaScript is different from this in common languages,
In the common language (java, c++, etc.), this usually appears only in the class method, while this points to the object it calls, but in JavaScript, this is more flexible, no matter where it appears or what it represents.
Pointing under the global action of this
This question is very easy to answer. In the browser, this points to the global object window
console.log(this) // window object var name = "hhf" console.log(this.name) // hhf console.log(window.name) // hhf
However, this is rarely used directly under the global action in development, and it is usually used in functions
What does this point to?
Let's pass a piece of code. In the code, we define a function and call it in three different ways, which produces different results
function foo() { console.log(this) } foo() // window object const obj = { name: "hhf", foo: foo } obj.foo() // obj1 const obj2 = {} foo.call(obj2) // obj2
From the results of running the above code, we can conclude that:
1. When calling a function, JavaScript will bind a value to this by default;
2. The binding of this has nothing to do with the defined location (the location of writing);
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:
1. Default binding
2. Implicit binding
3. Explicit binding
4.new binding
Let's learn these four binding rules respectively
Default binding
The default binding is usually bound when an independent function is called. We can understand that an independent function call is not bound to an object for calling. The default binding points to window in the browser and undefined when it is in use strict mode
// Case 1 function foo() { console.log(this) } foo() // window object // Case 2 function foo(fn) { fn() } const obj = { name: "hhf", bar: function() { console.log(this) } } foo(obj.bar) // window
Show bindings
Display binding is usually called by an object. Generally speaking, it points to whoever calls it
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 nested objects calling a function, such as objects Object Function, 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 call, apply and bind to bind this of the function
Different usage methods: call and apply call the function when it is called, and bind will return a new function
The purpose of display binding: anti shake, throttling, etc
Use of call function
The call() method calls a function with a specified value of this and one or more parameters given separately.
The parameters it receives are: the first is the bound this, followed by the parameters of the called function
The specific application methods are as follows
// Basic use function foo() { console.log(this.name); } const obj = { name: "hhf" } foo.call(obj) // hhf // Incoming parameters 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 the apply function
The syntax and function of the apply method are similar to the call() method, except that the call() method accepts a parameter list, while the apply() method accepts an array containing multiple parameters.
The specific application methods are 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 receives the same parameters as the call function, but it will return a new function, and the new function's 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 a function is called with a new operation, the following operations will be performed
1. A new object will be created inside the function
2. Prototype of the created object (_proto_) Will point to the prototype of the function
3. The created object will be bound to 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 that if a function uses multiple binding rules when calling, who has the highest priority?
give the result as follows
1. The default rule has the lowest priority. p there is no doubt that the default rule has the lowest priority, because when there are other rules, this will be bound by other rules
2. Display binding has higher priority 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 binding priority of new is higher than that of bind
new binding, call and apply are not allowed to be used at the same time, so there is no higher priority
new binding can be used together with bind. new binding has higher priority than p code testing
function foo() { console.log(this) } const obj1 = { name: 'obj1', foo: foo } const newFoo = foo.bind(obj1) new newFoo() // foo {}
this of the arrow function
Arrow function is a new function writing method in ES6, but the arrow function is not bound to this. When this is used in the arrow function, it will find it on the scope network and use this of the nearest scope
// Use normal functions const obj1 = { name: 'obj1', foo: function() { console.log(this) } } obj1.foo() // obj1 // Use arrow function const obj1 = { name: 'obj1', foo: ()=> { console.log(this) } } obj1.foo() // The upper scope of window foo is window // If the function passed in by setTimeout is an ordinary function, it is bound to the global object window. If an arrow function is passed in, its this execution is the this point of its upper scope const obj1 = { name: 'obj1', bar: function() { setTimeout(()=> { console.log(this) }) } } obj1.bar() // obj1
Now let's do a little exercise on what we just learned through a problem
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 result is
/* window window person2 obj person2 obj */
springboot e-commerce project mall4j( https://gitee.com/gz-yami/mall4j)