In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-03-27 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/01 Report--
This article mainly shows you "how to use the this direction of JavaScript". The content is simple and clear. I hope it can help you solve your doubts. Let the editor lead you to study and learn how to use the this direction of JavaScript.
The this of a function is bound when it is called, depending entirely on where the function is called (that is, the method of calling the function). In order to figure out what the this points to, you must know how the relevant functions are called.
Global context
In both non-strict mode and strict mode, this points to the top-level object (window in the browser).
This = window / / true'use strict'this = = window;this.name = 'W3C normal function call mode / / non-strict mode var name =' window';var doSth = function () {console.log (this.name);} doSth (); / / 'window'
You may mistakenly think that window.doSth () is called, so it points to window. Although in this case window.doSth does equal doSth. Name equals window.name. In the above code, this is because in ES5, global variables are mounted in the top-level object (the browser is window). In fact, this is not the case.
/ / non-strict mode let name2 = 'window2';let doSth3 = function () {console.log (this = window); console.log (this.name2);} doSth3 () / / true, undefined
In this example, let does not add attributes to the top-level object (the browser is window), and both window.name2 and window.doSth are undefined.
In strict mode, this in ordinary functions behaves differently, as undefined.
/ / strict mode 'use strict'var name =' window';var doSth = function () {console.log (typeof this = 'undefined'); console.log (this.name);} doSth (); / / true,// reports an error because this is undefined
Readers of "JavaScript you don't know" should know that this is called default binding in the book. Readers who are familiar with call,apply will be analogous to:
DoSth.call (undefined); doSth.apply (undefined)
The effect is the same. One of the functions of call,apply is to modify the this pointing to the first parameter in the function. The first parameter is undefined or null, which, in non-strict mode, points to window. In strict mode, you point to the first parameter. It will be explained in detail later. There is often this kind of code (callback function), which is actually a normal function call pattern.
Var name = 'W3C alternative setTimeout (function () {console.log (this.name);}, 0); / / Syntax setTimeout (fn | code, 0, arg1, arg2,...) / / can also be a string of code. You can also pass other functions / / analogies inside setTimeout functions to call fn or execute the code `code`. Fn.call (undefined, arg1, arg2,...); function (method) call pattern in the object var name = 'window';var doSth = function () {console.log (this.name);} var student = {name:' W3C calls, doSth: doSth, other: {name: 'other', doSth: doSth,}} student.doSth (); / / student.other.doSth () / / 'other'//: student.doSth.call (student) in call analogy; / / student.other.doSth.call (student.other) in call analogy
However, there are often the following scenarios in which the function in the object is assigned to a variable. This actually becomes a normal function again, so use the rules of ordinary functions (default binding).
Var studentDoSth = student.doSth;studentDoSth (); / / 'window'// call analogy is: studentDoSth.call (undefined); call, apply, bind invocation mode
Call and apply are mentioned above, which are interpreted in detail here. First get to know the call and apply MDN documents through MDN: Function.prototype.call ().
Grammar
Fun.call (thisArg, arg1, arg2,...)
The method value specified by thisArg when the fun function is running. It is important to note that the specified this value is not necessarily the real one when the function is executed. If the function is in non-strict mode, the this value specified as null and undefined will automatically point to the global object (that is, the object in the browser), and the This value with the original value (number, string, Boolean value) will point to the automatic wrapper object of the original value. Arg1, arg2,... The return value of the specified parameter list is the return value of the method you called, or undefined if the method has no return value. Apply is similar to call. Only the parameters are different. Its argument is an array (or class array).
According to the description of the parameter thisArg, call is to change the this in the function to thisArg and execute the function, which makes JavaScript much more flexible. In strict mode, thisArg is the original value is the value type, that is, the original value. Will not be packaged as an object. For example:
Var doSth = function (name) {console.log (this); console.log (name);} doSth.call (2, 'W3C'); / / Number {2}, 'W3Cschool'var doSth3 = function (name) {' use strict'; console.log (this); console.log (name);} doSth3.call (2, 'W3C'); / / 2, 'W3Cschool you'
Although the thisArg parameter is not generally written as a value type. But you still need to know this knowledge. I wrote an article before: the interviewer asked: can you simulate the call and apply methods of JS is to use the function this on the object to point to this object to simulate the implementation of call and apply. Interested readers think about how to achieve it, and then take a look at the author's realization.
Bind is similar to call and apply, the first parameter is to change the this point, except that the return value is a new function, and the new function can also be called as a new. MDN Function.prototype.bind
The bind () method creates a new function whose this key value is the value provided when the new function is called, and the first few values of its parameter list are the parameter sequence specified at the time of creation. Syntax: fun.bind (thisArg [, arg1 [, arg2 [,...]) Parameter: the value passed to the target function as a this parameter when thisArg calls the binding function. If the binding function is constructed using the new operator, this value is ignored. When you use bind to create a function in setTimeout (provided as a callback), any raw values passed as thisArg are converted to object. If no bound parameters are provided, the this that executes the scope is treated as the thisArg of the new function. Arg1, arg2,... When the bound function is called, these parameters are passed to the bound method before the argument. The return value returns a copy of the original function modified by the specified this value and initialization parameters.
I have also written an article before: how to simulate the bind method of implementing JS is to simulate the implementation of bind by using call and apply to point to this thisArg parameter. Interested readers think about how to achieve it, and then take a look at the author's realization.
Constructor call pattern function Student (name) {this.name = name; console.log (this); / / {name: 'W3C'}} / / equivalent to returning / / return this;} var result = new Student ('W3C')
Calling the function using the new operator automatically performs the following steps.
Created a whole new object.
This object will be linked to [[Prototype]] (that is, _ _ proto__).
The generated new object is bound to the this of the function call.
Each object created through new will eventually be linked to the prototype object of this function by [[Prototype]].
If the function does not return the object type Object (including Functoin, Array, Date, RegExg, Error), then the function call in the new expression automatically returns the new object.
You can see that when the new operator is called, the this points to the generated new object. In particular, the return value when new is called, if the object or function is not explicitly returned, is the new object that is returned.
Function Student (name) {this.name = name; / / return function f () {}; / / return {};} var result = new Student ('W3C'); console.log (result); {name: 'W3C'} / / if function f is returned, result is function f, if object {}, result is object {}
Many people or articles ignore this point and simply use typeof to judge the object. Although the return will not be displayed in actual use, the interviewer will ask.
Previously, I wrote an article in which the interviewer asked: can you simulate the new operator that implements JS, using apply to point the this to the generated newly generated object. Interested readers think about how to achieve it, and then take a look at the author's realization.
The invocation pattern in the prototype chain function Student (name) {this.name = name;} var S1 = new Student ('W3C chains'); Student.prototype.doSth = function () {console.log (this.name);} s1.doSth (); / / 'W3C chains'
You'll find this deja vu. This is the method invocation pattern on the object. Naturally, it points to the generated new object. If the object inherits from another object. It will also be found through the prototype chain. The above code is written using class in ES6 as follows:
Class Student {constructor (name) {this.name = name;} doSth () {console.log (this.name);}} let S1 = new Student ('Ruochuan'); s1.doSth ()
For the result of converting babel es6 to es5, you can go to the babeljs website conversion test to try it yourself.
'use strict';var _ createClass = function () {function defineProperties (target, props) {for (var I = 0; I)
< props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }var Student = function () { function Student(name) { _classCallCheck(this, Student); this.name = name; } _createClass(Student, [{ key: 'doSth', value: function doSth() { console.log(this.name); } }]); return Student;}();var s1 = new Student('W3Cschool');s1.doSth(); 由此看出,ES6的class也是通过构造函数模拟实现的,是一种语法糖。 箭头函数调用模式 先看箭头函数和普通函数的重要区别: 1、没有自己的this、super、arguments和new.target绑定。 2、不能使用new来调用。 3、没有原型对象。 4、不可以改变this的绑定。 5、形参名称不能重复。 箭头函数中没有this绑定,必须通过查找作用域链来决定其值。 如果箭头函数被非箭头函数包含,则this绑定的是最近一层非箭头函数的this,否则this的值则被设置为全局对象。 比如: var name = 'window';var student = { name: 'W3Cschool', doSth: function(){ // var self = this; var arrowDoSth = () =>{/ / console.log (self.name); console.log (this.name);} arrowDoSth ();}, arrowDoSth3: () = > {console.log (this.name);}} student.doSth (); / / 'W3Cschool'student.arrowDoSth3 (); / /' window'
In fact, it is equivalent to the this outside the arrow function is the cached this of the ordinary function above the arrow function. If there is no ordinary function, it is a global object (window in the browser). That is, the this of the arrow function cannot be bound through call, apply, or bind (it does not have a this of its own). On the other hand, call, apply, and bind can bind the this of ordinary functions above the cache arrow function. For example:
Var student = {name: 'W3C clients, doSth: function () {console.log (this.name); return () = > {console.log (' arrowFn:', this.name);} var person = {name: 'person',} student.doSth (). Call (person); / /' W3C''arrowFn:'' W3Cschool'student.doSth.call (person) () / / 'person'' arrowFn:' 'person'DOM event handler calls addEventerListener, attachEvent, onclickonclick 123 var button = document.querySelector (' button'); button.onclick = function (ev) {console.log (this); console.log (this = ev.currentTarget); / / true} var list = document.querySelector ('.list') List.addEventListener ('click', function (ev) {console.log (this = list); / / true console.log (this = ev.currentTarget); / / true console.log (this); console.log (ev.target);}, false)
Onclick and addEventerListener are elements that point to binding events. Some browsers, such as IE6~IE8, use attachEvent,this to point to window. By the way: interviewers also often examine the difference between ev.currentTarget and ev.target. Ev.currentTarget is the element that binds the event, and ev.target is the element that currently triggers the event. For example, here are ul and li. But it is also possible to click on ul, where ev.currentTarget and ev.target are equal.
Call the inline event handler and click me again.
The first is button itself, so it is true, and the second is window. This has nothing to do with strict mode. Of course, we don't use it like this now, but sometimes we accidentally write it like this, and we need to understand it.
In fact, there are many scenarios for the use of this, such as getter in the object object, this,new Function () in setter, and eval. But mastering the above several, to analyze others, will naturally be easily solved. Ordinary function calls, object function calls, new calls, call, apply, bind calls, and arrow function calls are more commonly used. So what are their priorities?
Priority
The this of the arrow function is the this of the upper-level ordinary function or the global object (window in the browser), so excluding it is not a priority.
Var name = 'window';var person = {name:' person',} var doSth = function () {console.log (this.name); return function () {console.log ('return:', this.name);}} var Student = {name:' W3C subscription, doSth: doSth,} / ordinary function call doSth (); / / function call Student.doSth () on window// object / / 'W3Cschool'// call, apply call Student.doSth.call (person); / /' person'new Student.doSth.call (person)
Imagine that if Student.doSth.call (person) executes first, new executes a function. There is no problem. In fact, however, the code reported an error. The operator precedence new is lower than the period, so new (Student.doSth.call) (person) is executed while Function.prototype.call, although a function (apply, bind is also a function), like the arrow function, cannot be called with new. So the report was wrong.
Uncaught TypeError: Student.doSth.call is not a constructor
This is because there are two different methods inside the function: [[Call]] and [[Constructor]]. [[Call]] is executed when a normal function call is used. [[Constructor]] is executed when a constructor call is used. There is no [[Constructor]] method inside the call, apply, bind, and arrow functions.
From the above example, we can see that ordinary function calls have the lowest priority, followed by functions on objects. The priority of call (apply, bind) call mode and new call mode is compared with bind and new in "JavaScript you don't know". The ployfill implementation of bind of mdn is referenced, and the function after bind when new is called will ignore the first parameter of bind binding. (actually, there are still some questions about the implementation of mdn. Readers who are interested can see my previous article: the interviewer asked: can you simulate the bind method for implementing JS) Indicates that the call to new has the highest priority. So their priority is new calls > call, apply, bind calls > function calls on objects > normal function calls.
Summary
If you want to determine the this binding of a running function, you need to find the location where the function is called directly. Once found, you can sequentially apply the following four rules to determine the bound object of this.
New call: bind to the newly created object, note: display the return function or object, and the return value is not the newly created object, but the explicitly returned function or object.
Call or apply (or bind) call: in strict mode, bind to the first parameter specified. In non-strict mode, null and undefined point to the global object (window in the browser), and the rest points to the object wrapped by new Object ().
Function call on object: bind to that object.
Normal function call: bind to undefined in strict mode, otherwise bind to global object.
Arrow function in ES6: instead of using the above four standard binding rules, the this is determined according to the current lexical scope. Specifically, the arrow function inherits the outer function, and the this binding called (no matter what the this is bound to). If there is no outer function, it is bound to the global object (window in the browser). This is actually the same as the self = this mechanism in the previous ES6 code.
DOM event function: generally points to the DOM element that binds the event, but in some cases binds to a global object (such as IE6~IE8 's attachEvent).
It is important to note that some calls may inadvertently use ordinary function binding rules. If you want to ignore this binding "more safely", you can use an object, such as ø = Object.create (null), to protect the global object.
The above is all the content of the article "how to use the this of JavaScript". Thank you for reading! I believe we all have a certain understanding, hope to share the content to help you, if you want to learn more knowledge, welcome to follow the industry information channel!
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: 268
*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.