javascript关键字
this in javascript always points to an object that is related to the environment in which the function is executed at runtime, i.e. it is dynamically bound to the environment in which the function is executed, not to the environment in which the function was declared.
javascript中的this始终指向与在运行时执行功能的环境相关的对象,即,它动态绑定到执行该功能的环境,而不是声明该功能的环境。
There are many reasons why javascript is difficult to master, one of which is that this
sometimes doesn’t work the way we expect it to.
有很多原因,JavaScript是很难掌握的,其中之一是, this
有时不工作,我们期望它的方式。
So I’ve summarized below a few scenarios where we’ll encounter this
in our work:
所以我总结以下几种情况中,我们会遇到this
对我们的工作:
Object method
对象方法
Function
功能
Constructor
建设者
with
与
eval
评估
1.对象方法(1. Object method)
this
points to an object when a function is called as a method of that object.
this
指向对象时一个函数被调用作为该对象的方法。
var age = 2;
const person = {
age: 1,
doSomething() {
console.log(this === person); // output: true
console.log(this.age); // output: 1
},
};
person.doSomething();
The age
declaration in the first line is equivalent to:
第一行中的age
声明等同于:
window.age = 2;
So the global object window
also has an age property, but since this
is the person
object we’re pointing to, we output the age
value of 1.
因此,全局对象window
也具有age属性,但是由于this
是我们要指向的person
对象,因此我们输出的age
值为1。
2.功能 (2. Function)
When a function is not called with an object attribute (i.e. a normal function), this always points to a global object, which in the browser is “window”.
如果未使用对象属性调用函数(即普通函数),则该对象始终指向全局对象,该对象在浏览器中为“窗口”。
var age = 2;
const person = {
age: 1,
doSomething(name) {
console.log(this === person);
console.log(this.age);
console.log(name);
},
};
const extractFn = person.doSomething;
extractFn('rick'); // false 2 rick
extractFn.call(person, 'rick'); // true 1 rick
extractFn.apply(person, ['rick']); // true 1 rick
We extracted the doSomething
function and named it extractFn
, and then executed it again.
我们提取了doSomething
函数并将其命名为extractFn
,然后再次执行它。
At this point extractFn
is no longer attached to the person
object, it has this pointing to the window object.
此时extractFn
不再附着在person
的对象,它有这个指向window对象。
So how do we make sure that extractFn
is called correctly?
那么,如何确保正确调用extractFn
?
Your can use Function.prototype.call and Function.prototype.apply can dynamically change the function’s this.
您可以使用Function.prototype.call和Function.prototype.apply可以动态更改函数的this。
The difference between call
and apply
is that call
needs to be passed one by one when there are multiple arguments, while apply
receives an array of arguments.
call
和apply
之间的区别在于,当有多个参数时, call
必须一次传递,而apply
接收一个参数数组。
3.构造函数 (3. Constructor)
When the function is called with the new operator, it returns an object with this pointing to itself.
当使用new运算符调用该函数时,它将返回一个指向该对象的对象。
As we all know, javascript is just a scripting language, there is no complete implementation of the class, but we can simulate the creation and use of the class through the prototype chain, the key point is the use of this
keyword.
众所周知,javascript只是一种脚本语言,没有完整的类实现,但是我们可以通过原型链来模拟类的创建和使用,关键是使用this
关键字。
function Person(name, age) {
this.name = name;
this.age = age;
this.getName = function() {
return this.name;
}
}
Person.prototype.getAge = function() {
return this.age;
}
const person1 = new Person('rick', 14);
const person2 = new Person('morty', 60);
console.log(person1.getName()); // output: rick
console.log(person1.getAge()); // output: 14
4.用(4. with)
Usually used as a shortcut to duplicate multiple attributes of an object, can be used without duplicating the object itself.
通常用作复制对象的多个属性的快捷方式,可以在不复制对象本身的情况下使用。
const obj = {
a: 1,
b: 2,
c: 3,
};
with (obj) {
a = 3;
b = 4;
c = 5;
}
console.log(obj) // output: {a: 3, b: 4, c: 5}
It looks great, but one fatal problem with with
is that when you accidentally assign a value to a property that doesn’t exist, it will leaks into the global scope!
它看起来不错,但有一个致命的问题with
的是当你不小心一个值赋给一个属性,它不存在,它会泄漏到全球范围内!
const obj = {
a: 1,
b: 2,
c: 3,
};
with (obj) {
d = 4;
}
console.log(obj) // output: {a: 1, b: 2, c: 3}
console.log(window.d); // output: 4
Which is a strange side effect, so with is completely disabled in strict mode.
这是一个奇怪的副作用,因此在严格模式下完全禁用。
5.评估 (5. eval)
This function accepts a string as an argument, and treats its contents as if the code already existed at that location in the program at the time it was written.
该函数接受一个字符串作为参数,并将其内容视为在编写代码时程序中该位置已经存在该代码。
const age = 2;
function example(str) {
eval(str);
console.log(age);
}
example('const age=3;'); //output:2
example("'use strict'; var age=6;"); //output:2
example('var age=4;'); // output: 4
In strict mode eval
has its own lexical scopes, so if the above program runs in strict mode the output will be 2, and eval
will change its scopes at runtime, which can cause all sorts of serious problems if you let your users type in commands.
在严格模式下, eval
有其自己的词法作用域,因此,如果上述程序在严格模式下运行,输出将为2,并且eval
将在运行时更改其作用域,如果让用户键入命令,则可能导致各种严重问题。
with和eval非常特别且功能强大,但是除非您有特定需求,否则我不建议您使用它们。 (with and eval are very special and powerful, but I don’t recommend using them unless you have a specific need for them.)
Thanks for reading, this is my first post on medium, I hope you’ll enjoy it.
感谢您的阅读,这是我在媒体上的第一篇文章,希望您会喜欢。
翻译自: https://medium.com/swlh/what-you-should-know-about-this-keyword-in-javascript-f61589298ca9
javascript关键字