Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What is this?

2025-01-15 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

This article mainly explains "what is this". The content of the explanation is simple and clear, and it is easy to learn and understand. Please follow the editor's train of thought to study and learn "what is this".

What on earth is this?

In fact, this is a pointer, which indicates a current execution environment, which can be used to perform some operations on the current execution environment. Because it indicates the execution environment, when you define this variable, you don't know its true value, and only the runtime can determine its value. The same piece of code, executed in different ways, may have different this directions. Let's take a look at the following code:

Function func () {this.name = "Xiao Fei"; console.log (this); / / Let's see what this is.

This method is simple, just adds a name attribute to this, and we copy this method to the Chrome debugger to see the result:

In the figure above, we directly called func () and found that this points to the window,name attribute added to the window. Let's change the invocation method and change it to new func ():

We see the output of two func {name: "Xiao Fei"}, one is the object returned by our new, and the other is the console in the method. The two values are the same, indicating that the this in the method points to the object returned by new instead of the window in the previous example. This is because when you use new to call a method, the method is actually used as a constructor, and the this points to the object coming out of the new.

Let's explain the following situations respectively.

When using the new call, this points to the object coming out of the new

This rule is actually part of JS object-oriented, which JS uses in a very tortuous way to support object-oriented. When you use new to execute a function, the function becomes a class, and the new keyword returns an instance of the class to you, which acts as a constructor. As an object-oriented constructor, you must have the ability to initialize properties to the instance, so there must be some mechanism in the constructor to manipulate the generated instance, which is this. Let this point to the generated instance and you can manipulate the instance through this. You can see this article for a more detailed explanation of object-oriented JS.

There are also some wonderful uses of this feature of this. A function can be called directly or with new, so what if I just want the user to call it through new? The following figure is taken from the Vue source code:

Vue cleverly takes advantage of the features of this to detect whether the consumer is called through new or directly by checking whether this is an instance of Vue.

When there is no clear caller, this points to window

This is actually mentioned at the beginning of the example, where there is no clear caller, this points to window. Let's talk about another example here, the function in the function, who does this point to?

Function func () {function func2 () {console.log ('this:', this); / / who does the this here point to? } func2 ();}

Let's take a look at the execution:

Direct execution:

Use new to execute:

We found that whether it is executed directly or using new, the value of this points to window. It is easy to understand when executing directly, because there is no clear caller, then this is naturally window. It should be noted that when using new, only the func of the new is the constructor, his this points to the object out of new, and the this of his function still points to window.

When there is an explicit caller, this points to the caller

Look at this example:

Var obj = {myName: "Xiaofei", func: function () {console.log (this.myName);}} obj.func (); / / Xiaofei

The above example is easy to understand, because the caller is obj, so the this in func points to obj,this.myName, which is obj.myName. In fact, this one can be combined with the previous one, when there is no clear caller, the implied caller is window, so it is often said that this always points to the caller.

Let's change this example a little bit:

Var myName = "Big Brother Fei"; var obj = {myName: "Xiao Fei", func: function () {console.log (this.myName);}} var anotherFunc = obj.func; anotherFunc (); / / what is the output?

The output here should be "Big Brother Fei", because although the function body of anotherFunc is the same as obj.func, but his execution environment is different, he actually does not have a clear caller, or the caller is window. The this.myName here is actually window.myName, that is, "Big Brother Fei".

Let's change this example again:

Let myName = "Big Brother Fei"; var obj = {myName: "Xiao Fei", func: function () {console.log (this.myName);}} var anotherFunc = obj.func; anotherFunc (); / / notice that the output here is undefined

This time we just changed the first var to let, but our output became undefined. This is because let,const defines variables, even at the outermost layer, will not become attributes of window, only variables defined by var will become attributes of window.

The arrow function does not bind this

This means that the arrow function itself does not have a this. When the arrow function is declared to determine this, it will directly use the this of the current scope as its own this. In the previous example, we changed the function to the arrow function:

Var myName = "Big Fei"; var obj = {myName: "Xiao Fei", func: () = > {console.log (this.myName);}} var anotherFunc = obj.func; obj.func (); / / Big Fei anotherFunc (); / / Big Fei

The obj.func () output in the above code is also "Big Flying Brother", because obj declares the arrow function when it is created, at this time the arrow function will look for the current scope, because obj is an object, not a scope, so the scope here is window,this, that is, window.

Let's look at another example:

Var myName = "Big Fei Brother"; var obj = {myName: "Xiao Fei", func: function () {return {getName: () = > {console.log (this.myName);} var anotherFunc = obj.func (). GetName; obj.func (). GetName (); / Xiao Fei anotherFunc (); / Xiao Fei

Both outputs are "little fly", obj.func (). GetName () output "little fly" is easy to understand, where the arrow function is declared in the return value of obj.func (), then his this is actually the this of func (), because he is called by obj, so this points to obj.

So why is the anotherFunc () output also "Xiao Fei"? This is because the this output by anotherFunc () is actually determined when the anotherFunc is assigned:

Var anotherFunc = obj.func (). GetName; actually executes obj.func () first

The getName arrow function is declared when obj.func () is executed

At this point, the this of the arrow function should be the this of the current scope, that is, the this in func ().

Func () is called by obj, so this points to obj

When you call anotherFunc, this has already determined, that is, obj, and the final output is obj.myName.

Let's take a look at the arrow function in a constructor. We talked about the function in the constructor. When it is called directly, its this points to window, but what if this function is an arrow function:

Var myName = "Big Brother Fei"; function func () {this.myName = "Xiao Fei"; const getName = () = > {console.log (this.myName);} getName ();} new func (); / / output what?

The output here is "Xiao Fei", and the principle is the same. When the arrow function is declared, this is determined to be the this of the current scope, which in this case is the scope of func, pointing to the instance out of new like the this of func. If you don't use new, but call it directly, the this here points to window.

In the DOM event callback, this points to the object that binds the event

Function func (e) {console.log (this = e.currentTarget); / / always true console.log (this = e.target); / / if target equals currentTarget, this is true} const ele = document.getElementById ('test'); ele.addEventListener (' click', func)

CurrentTarget refers to the DOM object that binds the event, and target refers to the object that triggers the event. In DOM event callback, this always points to currentTarget. If the object that triggers the event happens to be the object bound to the event, that is, target = = currentTarget,this will also point to target. If the callback is an arrow function, this is the this of the scope when the arrow function is declared.

In strict mode, this is undefined

Function func () {"use strict" console.log (this);} func (); / / output is undefined

Note that when this is undefined in strict mode, it means that inside the function body, if it is in the global scope, this still points to window.

... "use strict" console.log (this); / / window

Can this change it?

This can be changed, both call and apply can be modified and a bind function has been added to this,ES6.

Modify this using call and apply

Const obj = {myName: "Big Fei", func: function (age, gender) {console.log (`My name is ${this.myName}, my age is ${age}, I am a ${gender} `);}} const obj2 = {myName: "Xiao Fei"} obj.func.call (obj2, 18, "handsome") / / my name is Xiaofei, my age is 18, I am a handsome guy

Notice that the name of the output above is "Xiao Fei", that is, obj2.myName. The name of the normal direct call to obj.func () output should be obj.myName, that is, "Big Brother Fei". But if you use call to call, the first argument to call is the manually specified this. We specify it as obj2, so the this.myName in the function is actually obj2.myName.

The function of the apply method is similar to that of the call method, except that the form of the following function parameters is different. If you use apply calls, you should write that the function parameters should be put in an array or class array:

Obj.func.apply (obj2, [18, "handsome guy"]); / / my name is Xiaofei, my age is 18, I am a handsome guy

The reason why there are call and apply two methods to achieve similar function, is to make it easy for everyone to use, if you get the parameters are one by one, then use call, but sometimes get the parameter is arguments, which is a built-in variable of the function, is a class array structure, represents all the parameters of the current function, then you can directly use apply, instead of expanding it.

Use bind to modify this

Bind is a method introduced by ES5, and you can also modify this, but calling it does not immediately execute the method itself, but returns a new method that modifies this:

Const obj = {myName: "Big Fei", func: function (age, gender) {console.log (`My name is ${this.myName}, my age is ${age}, I am a ${gender} `);}} const obj2 = {myName: "Xiao Fei"} const func2 = obj.func.bind (obj2); / / returns a new method func2 (18, "handsome Brother") that changes this to obj2 / / my name is Xiaofei, my age is 18, I am a handsome guy

The biggest difference between bind and call,apply is that call,apply executes the method immediately, while bind does not execute it immediately, but returns a new method for later use.

The bind function can also accept multiple parameters, and the second and subsequent parameters will be passed as arguments to the new function. For example, the previous bind can also be written as follows:

Const func3 = obj.func.bind (obj2, 18); / / notice that we have passed an age parameter func3 ("handsome guy") here; / / notice that only the gender parameter is passed here, and the age parameter is already in func3. The output is still: my name is Xiaofei, my age is 18, and I am a handsome guy.

Write your own call.

Knowing the role of call, let's write a call ourselves:

Function.prototype.myCall = function (... args) {/ / Parameter check if (typeof this! = = "function") {throw new Error ('Must call with a function');} const realThis = args [0] | | window; const realArgs = args.slice (1); const funcSymbol = Symbol (' func'); realThis [funcSymbol] = this / / the this here is the original method. Save it to the first parameter passed in / / adjust the method with the passed parameter. The this in the method is the passed parameter const res = realThis [funcSymbol] (.. realArgs); delete realThis [funcSymbol]; / / finally delete the temporarily stored original method return res; / / the return value to be executed}

Write your own apply.

The apply method is very similar to the call method, except that it takes the call parameters:

Function.prototype.myApply = function (... args) {if (typeof this! = = "function") {throw new Error ('Must call with a function');} const realThis = args [0] | | window; / / take the second parameter directly, which is an array const realArgs = args [1]; const funcSymbol = Symbol (' func'); realThis [funcSymbol] = this; const res = realThis [funcSymbol] (. RealArgs) Delete realThis [funcSymbol]; return res;}

Write your own bind.

To write a bind yourself, you need to use the previous apply. Note that its return value is a method.

Function.prototype.myBind = function (... args) {if (typeof this! = = "function") {throw new Error ('Must call with a function');} const _ func = this; / / original method const realThis = args [0] | | window; / / bound this const otherArgs = args.slice (1) / / take the latter parameter as the default parameter of the new function return function (... args2) {/ / return a method return _ func.apply (realThis, [... otherArgs,...args2]) / / splice storage parameters and new parameters, and then use apply to execute}} thank you for your reading. This is the content of "what is this". After the study of this article, I believe you have a deeper understanding of what this is, and the specific use needs to be verified in practice. Here is, the editor will push for you more related knowledge points of the article, welcome to follow!

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.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report