In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-16 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
JavaScript this misunderstanding and binding rules and common problems, many novices are not very clear about this, in order to help you solve this problem, the following editor will explain in detail for you, people with this need can come to learn, I hope you can gain something.
I believe that this in Javascript will make many students confused in their work and study, the author is also, after reading a variety of materials and practical work applications, did the following comb, the main content, including the long-term misunderstanding of this and this binding rules, arrow functions, the actual work scene problems encountered, I hope you can help with this confusion.
First, two kinds of misunderstandings
1. Point to yourself.
The first misunderstanding of this is that it is easy to understand this as pointing to the function itself. In fact, the direction of this cannot be determined in the function definition stage, and only when the function is executed can it be determined who the this points to. The actual this ultimately points to the object from which it is called.
In the following example, the function foo () is declared, and when foo.count=0 is executed, an attribute count is added like the function object foo. But the this in the internal code this.count of the function foo does not point to that function object. The object that foo (I) in the for loop uses is window, which is equivalent to window.foo (I), so the this in the function foo points to window.
Function foo (num) {this.count++; / / record the number of times foo is called} foo.count = 0; window.count = 0; for (let item0; I 5) {foo (I);}} console.log (foo.count, window.count); / / 0 4
two。 Point to the scope of the function
The second misunderstanding of this is that this points to the scope of a function.
The following code, which attempts to call the bar function in foo, depends on the environment.
Browser: there is no problem in the browser environment. The globally declared function is placed under the window object. The this in the foo function refers to the window object, and the variable an is not declared in the global environment, so the this.an in the bar function is naturally not defined and outputs undefined.
Node.js: in the Node.js environment, the declared function is not placed under the global global object, so calling the this.bar function in the foo function will report a TypeError: this.bar is not a function error. To run without reporting errors, omit the previous this when calling the bar function.
Function foo () {var a = 2; this.bar ();} function bar () {console.log (this.a);} foo ()
II. Four binding rules of This
1. Default binding
When a function call is a stand-alone call (a call without a function reference) and cannot call other binding rules, we give it a name "default binding", which binds to the global object in non-strict mode and to undefined in strict mode (use strict).
Call in strict mode:
'use strict' function demo () {/ / TypeError: Cannot read property 'a'of undefined console.log (this.a);} const a = 1; demo ()
Called in non-strict mode:
In the browser environment, an is bound to window.a, and the following code uses the variable a declared by var to output 1.
Function demo () {console.log (this.a); / / 1} var a = 1; demo ()
The following code declares the variable a using let or const and the result outputs undefined
Function demo () {console.log (this.a); / / undefined} let a = 1; demo ()
When giving an example, you actually want to focus on the default binding relationship of this, but you will find that the results of the above two kinds of code are also different because they are declared using var and let respectively. The reason is related to the concept of top-level objects.
Children's shoes mention this question in Issue: Nodejs-Roadmap/issues/11, which is also an oversight before. Let's briefly talk about the concept of top-level object. The attributes of top-level objects (browser environment refers to window, Node.js environment refers to Global) are equivalent to global variable attributes. Properties of top-level objects are declared using var and function, and let belongs to the ES6 specification, but the global variables declared by let, const and class in ES6 specification Properties that no longer belong to the top-level object.
two。 Implicit binding
It is contained by an object at the calling location of the function and has the context. See the following example:
Function child () {console.log (this.name);} let parent = {name: 'zhangsan', child,} parent.child (); / / zhangsan
The function uses the parent object context to refer to the function child when the function is called, which can be understood to mean that the parent object owns or contains the child function when it is called.
Hidden dangers of implicit binding:
The function that is implicitly bound, because some careless operations will lose the bound object, the default binding in the binding rule mentioned at the beginning will be applied, see the following code:
Function child () {console.log (this.name);} let parent = {name: 'zhangsan', child,} let parentparent2 = parent.child; var name =' lisi'; parent2 ()
Assigning the parent.child function itself to parent2, calling parent2 () is actually a function call without any modification, so the default binding is applied.
3. Show bindings
Show binding and implicit binding are understood literally, there is an opposite contrast, one is more direct, the other is more euphemistic, let's take a look at the respective meanings of the two rules:
Implicit binding: the this is implicitly bound to the function that the object's internal property points to (for example, the child property reference function function child () {} of the object parent in the above example) by indirectly referencing the function inside an object.
Show binding: mandatory binding calls are made when an object needs to be referenced. Js provides call () and apply () methods, and ES5 also provides a built-in method Function.prototype.bind.
The first argument to both the call () and apply () functions is to set the this object. The difference is that apply passes parameters as an array, while call passes them one by one.
Function fruit (... args) {console.log (this.name, args);} var apple = {name: 'Apple'} var banana = {name: 'banana'} fruit.call (banana, 'asides,' b') / / ['axiao,' b'] fruit.apply (apple, ['ajar,' b']) / / ['aqu,' b']
The following is an example of bind binding, which simply binds a value to the this of the function and returns the bound function. The information is output only when the fruit function is executed, for example:
Function fruit () {console.log (this.name);} var apple = {name: 'Apple'} fruitfruit = fruit.bind (apple); fruit (); / / Apple
In addition to the above call, apply, bind, you can also use context context, for example:
Function fruit (name) {console.log (`${this.name}: ${name}`);} const obj = {name: 'this is fruit',} const arr = ['apple', 'banana']; arr.forEach (fruit, banana); / / this is fruit: Apple / / this is fruit: banana
4. New binding
The new binding can also affect the this call, which is a constructor, and each new binding creates a new object.
Function Fruit (name) {this.name = name;} const F1 = new Fruit ('apple'); const f2 = new Fruit (' banana'); console.log (f1.name, f2.name); / / apple banana
III. Priority
If multiple binding rules are applied to the calling location of this, it has priority: new binding-> Show binding-> implicit binding-> default binding.
IV. Arrow function
The arrow function is not defined using the function keyword, nor does it use the four this standard specifications described above. The arrow function inherits from the this binding of the outer function call.
When fruit.call (apple) is executed, the arrow function this is bound and cannot be modified again.
Function fruit () {return () = > {console.log (this.name);}} var apple = {name: 'Apple'} var banana = {name: 'banana'} var fruitfruitCall = fruit.call (apple); fruitCall.call (banana); / / Apple
5. Several common problems in the use of This
1. Simulate classes through functions and prototype chains
The following example defines the function Fruit, then defines the info method on the prototype chain, and instantiates object F1 and defines object f2 to call the info method, respectively.
Function Fruit (name) {this.name = name;} Fruit.prototype.info = function () {console.log (this.name);} const F1 = new Fruit ('Apple'); f1.info (); const f2 = {name:' Banana'}; f2.info = f1.info; f2.info ()
After the output, the two results are different, because the this in the info method does not correspond to the context in which it is defined, but the context in which it is called. According to the binding rules mentioned above, it corresponds to the implicit binding rules.
Apple Banana
two。 Use the arrow function on the prototype chain
If you use constructors and prototype chains to simulate classes, you cannot define the arrow function on the prototype chain, because the this in the arrow function inherits the this binding of the outer function call.
Function Fruit (name) {this.name = name;} Fruit.prototype.info = () = > {console.log (this.name);} var name = 'Banana' const F1 = new Fruit (' Apple'); f1.info ()
3. Use in events
Take an example of Node.js. When used in an event, when our listener is called, if a normal function is declared, this will be pointed to the EventEmitter instance bound by the listener. If the arrow function is used, this will not point to the EventEmitter instance.
Const EventEmitter = require ('events'); class MyEmitter extends EventEmitter {constructor () {super (); this.name =' myEmitter';}} const func1 = () = > console.log (this.name); const func2 = function () {console.log (this.name);}; const myEmitter = new MyEmitter (); myEmitter.on ('event', func1); / / undefined myEmitter.on (' event', func2); / / myEmitter myEmitter.emit ('event') Is it helpful for you to read the above content? If you want to know more about the relevant knowledge or read more related articles, please follow the industry information channel, thank you for your support.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.