What JavaScript in "this" yes?

原文:What is “this” in JavaScript?

If you've done development using JavaScript library, then you may have noticed a particular keyword named this. Although this is very common in JavaScript, but fully understand this principle and how to use keywords in the code of a considerable number of developers who really is not easy. In this article, I will help you in-depth understanding of this mechanism and its work.
Before you begin, make sure that you have installed Node. Then, open a command line terminal and run the command node.

Global environment "this"

The working mechanism of this is not very easy to understand. By this we are placed in a different environment, namely to understand how this works. First, look at the global environment.

In the global environment, this is equivalent to the global object global.

1
2
this === global;
true;

But only in valid node in. If we apply the same code in the js file to run, the resulting output is false .

If you want to test the effect, you can create a file named index.js that contains the following code:

1
console.log(this === global);

Node then run the file using the command:

1
2
$ node index.js
false

The reason is that in the JavaScript file, this is equivalent to module.exports, rather than global.

The function of "this"

this function value is usually defined by the calling function. Therefore, every function is executed, this value may be different in function.

In index.js file, write a very simple function to check this is equal global object.

1
2
3
4
function () {
console.log(this === global)
}
rajat()

If we use the node running this code, the resulting output is true. If you add a "use strict" at the top of the file, and run it again, you will get a false output, because now this is undefined.
To further explain this, let's create a simple function to define the superhero's real name and the name of the hero

1
2
3
4
5
6
function Hero(heroName, realName) {
this.realName = realName;
this.heroName = heroName;
}
const superman= Hero("Superman", "Clark Kent");
console.log(superman);

Please note that this function is not to 严格模式write. node running this code, and we will not get the expected "Superman" and "Clark Kent", but it only gives us a undefined.

The reason behind this is because the function is not written in strict mode, this points to global objects .
If you 严格模式run this code down, we will receive an error, because JavaScript is not allowed to assign attributes realName and heroName undefined. In fact, this is a good thing, because it prevents us create a global variable.

In addition, function names written in upper case means that we need it as a constructor, to use the new operator to invoke. Alternatively last two lines of code above with the following code segment

1
2
onst superman = new Hero("Superman", "Clark Kent");
console.log(superman);

Run node index.js command again, and now will get your desired output.

Constructor "this"

JavaScript does not have a specific constructor. We can do is to use the new operator function call of the constructor call, shown in the previous section.
When the constructor is called, it creates a new object and set this argument to the function. Constructors implicitly return this object, unless we explicitly return another object.
Add the following return statement inside the hero function:

1
2
3
4
return {
heroName: "Batman",
realName: "Bruce Wayne",
};

If we run node command again, we will see return statement covering above the constructor call.

The only case return statement does not cover the constructor call is not an object returned by the return statement . In this case, the object will contain the original value.

The method of "this"

When the function is called as an object method, the object is the this point, also known as the receiver (Receiver) function call.
Suppose there is a dialogue target hero method, then this value points to the hero dialogue itself. At this point the hero also known as the recipient dialogue method call.

1
2
3
4
5
6
7
const hero = {
heroName: "Batman",
dialogue() {
console.log(`I am ${this.heroName}!`);
}
};
hero.dialogue();

This example is very simple, but in reality, our approach is difficult to track receivers. Add the following code snippet at the end of index.js.

1
2
const saying = hero.dialogue;
saying();

If I reference the dialogue is stored in another variable, and the variable as a function call. node running code, this will return undefined, because the method has lost the receiver. At this point this global, rather than a hero.

When we pass a method as a callback method to another, usually get lost receivers. We can add the wrapper function or use bindthe this object is bound to a particular method to solve this problem.

call () and apply ()

Although this is the implicit value of the function set, we can also use call when calling function () and apply () explicitly set this parameter.

We reconstruct the code fragment in the previous section, as follows:

1
2
3
4
5
6
function dialogue () { Console .log ( `the I AM $ { the this .heroName} ` ); } const Hero = {   heroName: Big Box   JavaScript in "this" what is? = S "String"> 'Batman' , };





If the receiver object as a hero To dialogue functions, we can use the call () or apply ():

1
2
3
dialogue.call(hero)

dialogue.apply(hero)

If you are using call or apply in non-strict mode, JavaScript engine will ignore or apply passed to the call of null or undefined (Translator's Note: being replaced by global). This is also one of the reasons why the recommendation has always been to write code in strict mode.

bind()

When we pass a method as a callback function to another, there is always a risk of loss of the original receivers method, so this parameter points to the global object.

bind()The method of this parameter may be bound to a fixed value. The following code fragments, bind creates a new dialogue functions, and this value is set hero. (Translator's Note: bind()method creates a new function, called binding function -bound function-BF, binding when calling this function, the function will be binding when creating it passed bind()first argument as this, incoming bind()method of the second and subsequent parameters plus parameters themselves to call the original function as a parameter in the order of the original function of binding function is running.)

1
2
3
4
5
6
7
const hero = {
heroName: "Batman",
dialogue() {
console.log(`I am ${this.heroName}`);
}
};
setTimeOut(hero.dialogue.bind(hero), 1000);

In this case, even if a call or apply this method can not change the value of.

Arrow function of "this"

this and other types of JavaScript functions in the arrow functions are very different. An arrow function uses the this value from its enclosing execution context, since it does have one of its own.

Arrow function permanently capture this value, apply or prevent subsequent changes to call it .

To explain how the arrow in this function works, let's write a function arrow:

1
2
3
4
5
const batman = this;
const bruce = () => {
console.log(this === batman);
};
bruce(); // true

这里,我们将 this值存储在变量中,然后将该值与箭头函数内的 this值进行比较。在终端中运行 node index.js,输出应该为 true 。

箭头函数内的 this值无法明确设置。此外,使用 call 、 apply或 bind等方法给 this传值,箭头函数会忽略。箭头函数引用的是箭头函数在创建时设置的 this值。(译者注:箭头函数中没有this绑定,必须通过查找作用域链来决定它的值,如果箭头函数被非箭头函数包裹,那么this值由外围最近一层非箭头函数决定,否则为undefined。

箭头函数也不能用作构造函数。因此,我们也不能在箭头函数内给 this设置属性。

那么箭头函数对 this 可以做什么呢?

箭头函数 可以使我们在回调函数中访问this 。通过下面的 counter对象来看看如何做到的:

1
2
3
4
5
6
7
8
9
const counter = {
count: 0,
increase() {
setInterval(function() {
console.log(++this.count);
}, 1000);
}
}
counter.increase();

使用 node index.js运行此代码,只会得到一个 NaN的列表。这是因为 this.count已经不是指向 counter对象了。它实际上指向的为 global对象。

如果想让计数器正常工作,可以使用箭头函数重写它。

回调函数使用 this与 increase方法绑定, counter现在可以正常工作了。

注意 :不要将 ++this.count 写成 this.count + 1。后者只会增加count的值一次,每次迭代都会返回相同的值。

Class中的“this”

类是JavaScript应用程序中最重要的一部分。让我们看看类中的this有何不同。

类通常包含一个 constructor , this可以指向任何新创建的对象

不过在作为方法时,如果该方法作为普通函数被调用, this也可以指向任何其他值。与方法一样,类也可能失去对接收器的跟踪。

我们将之前创建的 Hero函数改造为类。该类包含一个构造函数和一个 dialogue()方法。最后,创建一个类的实例并调用 dialogue方法。

1
2
3
4
5
6
7
8
9
10
class Hero {
constructor(heroName) {
this.heroName = heroName;
}
dialogue() {
console.log(`I am ${this.heroName}`)
}
}
const batman = new Hero("Batman");
batman.dialogue();

构造函数里的 this指向新创建的 类实例。当我们调用 batman.dialogue()时, dialogue()作为方法被调用, batman是它的接收器。

但是如果我们将 dialogue()方法的引用存储起来,并稍后将其作为函数调用,我们会丢失该方法的接收器,此时 this参数指向 undefined

1
2
const say = batman.dialogue;
say();

The error occurs is a JavaScript class is implicit run in strict mode. We are calling say in the absence of any automatic binding case () function. To solve this problem, we need to use to manually bind () to bind together dialogue () function and batman.

1
2
const say = batman.dialogue.bind(batman);
say();

We can also do this binding in the constructor method.

to sum up

We need to use this in JavaScript, just as we need to use pronouns in English. With these two words as an example:

  • Rajat loves DC Comics.
  • Rajat also loves Marvel movies.

We can use pronouns these two sentences together, so now the two sentences:

  • Rajat loves DC Comics, and he also loves Marvel Comics

This short grammar lesson perfectly explains the importance of this in JavaScript. Like the pronouns he, like two sentences together, this can be used as a shortcut reference again to the same content.

Original Address

Guess you like

Origin www.cnblogs.com/sanxiandoupi/p/11693075.html