In order to understand what this is, I will assume that you understand the execution context, and post a diagram of the execution context:
The reference to this is determined when the function is called. That is, when the execution context is created. So if you change the reference to this during execution, you will get an error
This in the global object
This in the global environment refers to itself
// Bind this to the global object this.a2 = 20; // Bind to a variable object by declaration, but in the global environment, the variable object is itself. // For assignment only, identifiers are implicitly bound to the global object A3 = 30;Copy the code
2. The function this
Var a = 'eeee' let obj= {console.log(this.a)} // a separate {} will not form a new scope, because there is no scope limit, it is still in the global scope.Copy the code
In the context of a function, this is provided by the caller, depending on how the function is called. If the caller function is owned by an object, the internal this refers to that object when the function is called. If this object is a single object, then the internal this refers to the global and if the function is called independently, then the internal this refers to undefined. But in non-strict mode, when this points to undefined, it is automatically referred to the global object.Copy the code
Arrow function
Arrow functions do not have their own this, super, arguments, and new.target bindings. 2. Cannot be called with new. 3. No prototype objects. 4. You cannot change the binding of this. 5. Parameter names must be unique.Copy the code
The this outside the arrow function is the this of the normal function above the cached arrow function. If there is no ordinary function, it is a global object
Call, apply, and bind can bind this to the normal function above the cache arrow function
function Person(name){
this.name = name;
this.say = () => {
var name = "xb";
return this.name;
}
}
var person = new Person("axuebin");
console.log(person.say()); // axuebin
Copy the code
None of the arrow functions have their own this, pointing to the outer layer. The arrow function captures the this value of its context as its own.
Constructor and this on prototype methods
Creating an object using the constructor actually performs the following steps: 1 create a new object 2 this object will be linked by the execution [[Prototype]] (that is, __proto__). Each object created by new will eventually be linked to the function's Prototype object by [[Prototype]]. 4 If the function does not return the type Object(including Functoin, Array, Date, RegExg, Error), So the function call in the new expression will automatically return this new object so this is referring to the object that was created. As a special reminder, the return value of the new call, if no explicit object or function is returned, is the generated new object. demo1: function Student(name){ this.name = name; // return function f(){}; // return {}; } var result = new Student(' new Student '); var str = typeof(result) console.log(result,str); } "demo2: function Person(name){this.name = name; this.age = 25; this.say = function(){ console.log(this.name + ":" + this.age); } } var person = new Person("axuebin"); console.log(person.name); // axuebin person.say(); // axuebin:25 demo3: function Student(name){ this.name = name; console.log(this); // {name: 'XRR '}} } var result = new Student('xrr'); console.log(result) // {name: 'xrr'}Copy the code
ES6’s class, also implemented through constructor emulation, is a syntactic sugar.
As a DOM event handler
This refers to the element that triggered the event, which is the DOM node to which the initial event handler is bound.
var ele = document.getElementById("id");
ele.addEventListener("click",function(e){
console.log(this);
console.log(this === e.target); // true
})
Copy the code
<button class="button">onclick</button> <ul class="list"> <li>1</li> <li>2</li> <li>3</li> </ul> <script> 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); </script> // onclick and addEventerListener are elements that point to binding events. // Some browsers, such as IE6 to IE8, use attachEvent, this refers to window // ev.currenttarget and ev.target are different: CurrentTarget is the element that binds the event, and ev.target is the element that currently fires the event. // Here are ul and li respectively. But it is also possible to hit ul, in which case ev.currentTarget and ev.target are equal.Copy the code
HTML tags inline event handlers
This refers to the DOM element
<button onclick="console.log(this);" >Click Me</button>Copy the code
JQuery’s this
In many cases, JQuery's This refers to DOM element nodes. $(".btn").on("click",function(){ console.log(this); });Copy the code
Call (point to target, A1, A2, A3), apply(point to target, [……] )
JavaScript internally provides a mechanism for manually setting the orientation of this. They are call and apply. They function exactly the same except for slightly different parameters. Both take the first argument to the object this will point to.
The arguments after call and applay pass arguments to the function to be executed. Where call is passed one by one and apply is passed as an array. That’s the only difference between them.
Call and apply are the same in terms of binding this, except for their second argument
function fn(num1, num2) { console.log(this.a + num1 + num2); } var obj = { a: 20 } fn.call(obj, 100, 10); // 130 fn.apply(obj, [20, 10]); / / 50Copy the code
Methods to convert a pseudo-array to an array:
Function exam(a, b, c, d, e) {function exam(a, b, c, d, e) {console.log(arguments); var arg = [].slice.call(arguments); // []. Slice -> returns a new empty array, and copies arguments into the empty array console.log(arg); } exam(2, 8, 9, 10, 3); // result: // [2, 8, 9, 10, 3, callee: ƒ, Symbol(symbol.iterator): ƒ] / [2, 8, 9, 10, 3] / / / / and often use this method converts the DOM nodelist array / / []. Slice. The call (the document. The getElementsByTagName (" li "));Copy the code
bind()
Bind and call are similar to apply in that the first argument changes this, except that the return value is a new function that can also be called as a constructor.
The bind() method creates a new function whose this key value is the value provided when the new function is called, and whose argument list starts with the sequence of arguments specified when the function is created.
This will be permanently bound to the first argument of bind.
inheritance
In the Student constructor, the parent constructor is executed once with the call method, which is equivalent to making a copy of the code in Person in Sudent, where this points to the instance object new from Student. The call method ensures that this points correctly, thus implementing inheritance. Student’s constructor is equivalent to the following.
var Student = function (name, age, high) { this.name = name; this.age = age; this.gender = ['man', 'woman']; // Person.call(this, name, age); This. High = high; this. }Copy the code
Ensure that the reference to this remains constant in passing to other execution contexts
var obj = { a: 20, getA: function () { setTimeout(function () { console.log(this.a) }, 1000) } } obj.getA(); // undefined // This pointer is missing due to the existence of an anonymous function. In this anonymous function, this refers to the global, so we need to find some way to retrieve the correct this pointer. var obj = { a: 20, getA: function () { var self = this; // The conventional solution is simply to use a variable, SetTimeout (function () {console.log(self.a)}, 1000)}} Var obj = {a: 20, getA: Function () {setTimeout(function () {console.log(this.a)}.bind(this), 1000)}} ES6 often uses arrow functions insteadCopy the code
particularity
Var name = 'window'; var doSth = function(){ console.log(this.name); } doSth(); // 'window' In ES5, global variables are mounted in the top-level object (browser is Window).Copy the code
// let name2 = 'window2'; let doSth2 = function(){ console.log(this === window); console.log(this.name2); } doSth2() // true, undefined let does not add attributes to the top-level object (browser is window), window.name2 and window.dosth are undefined.Copy the code
// Strict mode 'use strict' var name = 'window'; var doSth = function(){ console.log(typeof this === 'undefined'); console.log(this.name); } doSth(); // true, // error because this is undefinedCopy the code
If the function is in non-strict mode, this with null and undefined will automatically point to a global object (window in browsers), while this with a raw value (number, string, Boolean) will point to the auto-wrapped object of that raw value.
priority
Their priority is new calls > Call, apply, bind calls > function calls on objects > normal function calls.
conclusion
-
To determine a function’s this binding, you need to find where the function is called directly. We can then determine the binding object of this by following four rules in order:
- New call: bind to the newly created object, note: display a return function or object, the return value is not the newly created object, but the explicit return function or object.
- Call or apply (or bind) : In strict mode, bind to the first parameter specified. In non-strict mode, null and undefined point to global objects (Windows in browsers), and the rest of the values point to objects wrapped in new Object().
- Called by context object: Binds to context object
- Normal function calls: bind to undefined in strict mode, otherwise bind to global objects.
-
Arrow functions in ES6: Instead of using the four standard binding rules above, this is determined by the current lexical scope. Specifically, arrow functions inherit outer functions
Note: The arrow function does not use the above binding rules and determines this based on the outer scope, inheriting the this binding of the outer function call.
-
DOM event functions: Generally refer to DOM elements that are bound to events, but in some cases bind to global objects (such as attachEvent in IE6~IE8).
The interviewer can examine the use of new, call, apply, bind, arrow functions, and so on by examining this reference. This extends to scopes, closures, stereotype chains, inheritance, strict patterns, and so on.
Original link: if there is infringement, please contact the author to delete
Github.com/axuebin/art…
Github.com/mqyqingfeng…
www.jianshu.com/p/d647aa6d1…
Juejin. Cn/post / 684490…