JavaScript理解`this`

Java语言是this和that,还有其他几个: (Javascript’s this and that, and few others:)

The this keyword in javascript is perhaps the most ambiguous thing to follow through when we are writing code. It sometimes confuses even the most experienced javascript developers. This article aims at explaining all the concepts related to javascript, especially the parts were understanding the mechanism becomes tricky. Sit back and enjoy the journey.

javascript中的this关键字可能是我们编写代码时要遵循的最含糊的内容。 有时,即使最有经验的javascript开发人员也会感到困惑。 本文旨在解释与javascript相关的所有概念,尤其是那些了解该机制变得棘手的部分。 坐下来享受旅程。

this in javascript is used similarly to how pronouns are used in the English language. Usually, we write “Jensen is studying javascript because he wants to learn web development”. In the given example, note the usage of pronoun he to refer to John. The pronoun he acts as a referent to the person John. Similarly in Javascript, the keyword this acts as a referent to the object which is being executed in the current context.

javascript中的this用法与英语中的代词用法类似。 通常,我们写“ Jensen之所以学习JavaScript是因为他想学习Web开发”。 在给定的示例中,请注意代词he指代约翰的用法。 he代名词John 。 类似地,在Javascript中,关键字this充当对当前上下文中正在执行的对象的引用。

Consider the following example:

考虑以下示例:

var person = {
firstName: "Jensen",
lastName: "Ackles",
fullName: function () {
​//using this
console.log(this.firstName + " " + this.lastName);
​// using object name
console.log(person.firstName + " " + person.lastName);
}
}
person.fullName();

In the following code both this and person works, however, using the keyword this to refer to an object is favored for two reasons:

在以下代码中, thisperson可以使用,但是,使用关键字this来引用对象是受青睐的,原因有两个:

  1. A global object with the same name person could be present, and the code might try to access the global object.

    可能存在一个具有相同名字的person全局对象,并且代码可能会尝试访问该全局对象。

  2. Sometimes the name of the object is not known to the code which is executing it, this keyword simplifies it by bringing in the reference to the object which holds the current context.

    有时,执行该操作的代码不知道该对象的名称, this关键字通过引入对保存当前上下文的对象的引用来简化该对象。

Note that, this keyword can be used globally, however, in strict mode, this holds the value of undefined in global functions and in anonymous functions that are not bound to any object.

需要注意的是, this关键字可以在全球范围内使用,然而,在严格模式下this持有的全局函数和未绑定到任何物体匿名函数值undefined。

基础知识this :澄清误解 (Basics of this: Clarifying misunderstandings)

All javascript functions have properties, just like objects contain properties. Whenever a function is executed, it gets this property assigned to it with the value of the object that invokes the function. The property this ALWAYS holds the reference to the object, and it is usually used inside the function to access the properties and methods on the object.

所有的javascript函数都有属性,就像对象包含属性一样。 每当执行一个函数时,它都会使用调用该函数的对象 this属性分配给它。 属性this ALWAYS保持参考对象,并且它通常用于在函数内部访问该对象的属性和方法。

If we consider the above example, the fullName function is executed from the object person. The property this used inside the fullName function now refers to the object person.

如果考虑以上示例,则fullName函数从对象person执行。 属性this使用的全名函数内现指对象person

Big principle: The biggest concept to understand about the property this is the fact that, the value of this is not assigned until an object invoked the function. Even though it appears as if the value of this should be equal to the value of the object inside which the function is defined, that is not true. Until an object invokes the function where this is used, the value is not assigned, and the value of this is equal to the value of the object invoking the function in most circumstances. However, there are certain exceptional scenarios when this doesn't have the value of the invoking object, and these scenarios will be explained later.

大原则 :最大的概念来理解有关物业this是,价值的事实, this是没有分配到一个对象中调用的函数。 尽管看起来好像的值this应该等于在对象内部的值的函数被定义,这是不正确的。 直到一个对象调用其中函数this被使用,该值没有被分配,和的值this等于援引在大多数情况下的函数的对象的值。 不过,也有某些特殊情况下,当this没有调用对象的价值,而这些方案将在稍后解释。

在全球范围内: (This in global scope:)

The value of this as explained earlier contains the value of the invoking object. In the global scope, the code is executed in the browser, and all global variables and functions are defined on the object. Therefore, when this is used inside global functions, it holds the value of object. Consider the following example:

如前所述, this值包含调用对象的值。 在全局范围内,代码在浏览器中执行,所有全局变量和函数都在对象上定义。 因此,当this是全局函数内使用,它保存对象的值。 考虑以下示例:

var firstName = "Dean";
var lastName = "Winchester";
function showFullName() {
console.log(this.firstName + " " + this.lastName);
}
var person = {
firstName: "Jensen",
lastName: "Ackles",
showFullName: function () {
console.log(this.firstName + " " + this.lastName);
}
}
showFullName (); // Dean Winchester - this refers to global window object
window.showFullName (); // Dean Winchester - this refers to window object
person.showFullName (); // Jensen Ackles - this refers to person object

的情况下this是可以改变的 (The context of this can be changed)

Though we said that the value of this usually holds the value of the object which invokes the function, it can be changed in many scenarios. The common scenarios when the value of these changes are:

尽管我们说过this的值通常保存调用该函数的对象的值,但是在许多情况下可以更改它。 这些值的更改的常见情况是:

  • Borrowing a method that uses this

    借用一个使用方法this

  • Assign a method that uses this

    分配使用this方法

  • Callback function using this.

    使用this回调函数。

  • this used inside a closure.

    this用在一个闭包里面。

Let’s look at an example which demonstrates the possibility and then tackle different scenarios where value of this acts differently:

让我们看看这表明了可能性,然后应对不同场景中的值的例子this行为是不同的:

var person1 = {
firstName: "Jensen",
lastName: "Ackles",
showFullName: function () {
console.log(this.firstName + " " + this.lastName);
}
}
var person2 = {
firstName: "Dean",
lastName: "Winchester",
}
person1.showFullName (); // Jensen Ackles - this refers to person1 object
person1.showFullName.apply(person2); // Dean Winchester - this refers to person2 object

You can see how the value of this changed simply because we used to apply and forced the context of this to person2

你可以看到什么样的值this是因为我们使用的应用只是改变和强迫的情况下thisPERSON2

this在借用方法时: (this when borrowing methods:)

Borrowing methods is a common practice in javascript development. Sometimes methods are defined in a different object, and we would want to use it on our object without repeating the code. Considering the above example:

借用方法是javascript开发中的常见做法。 有时,方法是在另一个对象中定义的,我们希望在我们的对象上使用它而无需重复代码。 考虑以上示例:

var person1 = {
firstName: "Jensen",
lastName: "Ackles",
showFullName: function () {
return this.firstName + " " + this.lastName;
}
}
var person2 = {
firstName: "Dean",
lastName: "Winchester",
}
person2.fullName = person1.showFullName();
console.log(person2.fullName); // Jensen Ackles - this refers to person1 object
person2.fullName = person1.showFullName.apply(person2);
console.log(person2.fullName); // Dean Winchester - this refers to person2 object

Using apply during the execution of the method, and providing the object on which this value must be set will fix the problems when borrowing methods.

在执行方法期间使用apply并提供必须在其上设置this值的对象将解决借入方法时的问题。

this当一个方法分配给一个变量: (this when a method is assigned to a variable:)

The value of this gets assigned to the context of a different object when we assign a method that uses to a variable:

当我们为变量分配使用的方法时, this值将分配给另一个对象的上下文:

var person = {
firstName: "Jensen",
lastName: "Ackles",
fullName: function () {
return this.firstName + " " + this.lastName;
}
}
var showFullName = person.fullName;
console.log(showFullName()); // undefined undefined

Instead of getting the value “Jensen Ackles”, we got “undefined undefined”. This is because, when the method was borrowed, its context is not set to the global variable. Since the global window object doesn’t contain the value of firstName and lastName, they are printed as undefined. To fix this problem, we can set the value of this to a particular object indefinitely using bind:

我们没有得到值“ Jensen Ackles” ,而是得到了“ undefined undefined” 。 这是因为,当借用该方法时,其上下文未设置为全局变量。 由于全局窗口对象不包含firstNamelastName的值,因此将它们打印为undefined 。 为了解决这个问题,我们可以使用bind无限期地this值设置为特定对象:

var person = {
firstName: "Jensen",
lastName: "Ackles",
fullName: function () {
return this.firstName + " " + this.lastName;
}
}
var showFullName = person.fullName.bind(person);
console.log(showFullName()); // Jensen Ackles

this作为回调的方法内使用时: (this when used inside a method as a callback:)

The value of this goes out of context when it is used in a function provided as a callback:

当在作为回调提供的函数中使用this时,其值会脱离上下文:

var person = {
firstName: "Jensen",
lastName: "Ackles",
fullName: function () {
console.log(this.firstName + " " + this.lastName);
}
}
setTimeout(person.fullName, 1000); // undefined undefined

The above code works similarly to how the context of this changes when it is assigned to a variable. One can assume that the setTimeOut function has a variable that takes the function as a parameter, and then it executes on the global object. Since the global object doesn't contain the definition to firstName and lastName, the value is printed as undefined.

上面的代码工程的上下文如何类似this当它被分配给一个变量改变。 可以假定setTimeOut函数具有一个以该函数为参数的变量,然后在全局对象上执行。 由于全局对象不包含firstNamelastName的定义,因此该值将显示为undefined

To fix this, we need to bind the value of this to the object on which it should be applied. This is a pattern most commonly seen when we are defining callback functions to the javascript events.

要解决此问题,我们需要将this的值绑定到应在其上应用的对象。 当我们为javascript事件定义回调函数时,这是最常见的模式。

setTimeout(person.fullName.bind(person), 1000); // Jensen Ackles

this封闭内使用时: (this when used inside a closure:)

Another instance when the value of this is misunderstood is when this is used inside closures.

当的值的另一实例this时是被误解的是this是内部封闭件使用。

var person = {
fullName: "Jensen Ackles",
getDetails: function () {
var closureFunction = function() {
console.log(this.fullName); // undefined
console.log(this); // global window object
}
closureFunction();
}
}
person.getDetails();

The value of this doesn't refer to the person object, rather it refers to the global window object. We have two ways of mitigating this problem:

this并不是指人对象,而它指的是全局的window对象。 我们有两种方法可以缓解此问题:

  1. Assign the value of this to an explicit variable, and then use that variable to access the properties.

    的值分配给 this 一个明确的变量,然后使用该变量来访问属性。

var person = {
fullName: "Jensen Ackles",
getDetails: function () {
var personObj = this;
var closureFunction = function() {
console.log(personObj.fullName); // Jensen Ackles
console.log(personObj); // person Object
}
closureFunction();
}
}
person.getDetails();

2. Use arrow function provided by ES6: Arrow function preserves the context of this.

2.使用箭头由ES6提供的功能 :Arrow功能保留的情况下this

var person = {
fullName: "Jensen Ackles",
getDetails: function () {
var closureFunction = () => {
console.log(this.fullName); // Jensen Ackles
console.log(this); // person Object
}
closureFunction();
}
}
person.getDetails();

This article has aimed at providing a detailed understanding of how this is used in javascript and has warned about the pitfalls which can be avoided while using this. Using javascript's apply, call, bind, and arrow functions, we can control the value of this to meet our needs. As a final note, please remember that the value of this is usually the object on which the function is called.

本文旨在详细了解如何在javascript中使用this方法,并警告了使用this方法时可以避免的陷阱。 使用javascript的apply,call,bind和arrow函数 ,我们可以控制this的值以满足我们的需求。 最后一点,请记住,值this通常是在该函数被调用的对象。

Originally published at https://aparnajoshi.netlify.app.

最初发布在 https://aparnajoshi.netlify.app上

翻译自: https://medium.com/weekly-webtips/javascript-understanding-this-2b112a9afd95

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值