“这"是怎么回事?Javascript中的关键字在对象文字中起作用?
我看过 this"如何;关键字在函数中起作用?,但我没有看到它回答了以下问题.
I've seen How does "this" keyword work within a function?, but I don't see that it answers the following.
鉴于此代码:
var MyDate = function(date) {
this.date = date;
};
var obj1 = {
foo: new Date(),
bar: new MyDate(this.foo) // this.foo is undefined
};
var obj2 = {};
obj2.foo = new Date();
obj2.bar = new MyDate(this.foo); // this.foo is undefined
var obj3 = {
foo: new Date(),
bar: new MyDate(obj3.foo)
};
var obj4 = {};
obj4.foo = new Date();
obj4.bar = new MyDate(obj4.foo);
为什么前两次尝试失败,但后两次成功?如果 this
没有绑定到当前对象字面量,那么它绑定到什么 ?
Why do the first two attempts fail, but the last two work? If this
isn't bound to the current object literal, what is it bound to?
推荐答案
Javascript 是一种后期绑定语言.事实上,它是很晚的绑定.this
不仅在编译时不绑定,甚至在运行时也不绑定(就像大多数其他后期绑定语言一样).在 javascript 中,this
在调用期间被绑定.
Javascript is a late binding language. In fact, it is very late binding. Not only is this
not bound during compile time, it is not even bound during runtime (as most other late binding languages do). In javascript, this
is bound during call time.
绑定规则与大多数其他 OO 语言完全不同,这就是为什么它似乎让很多不熟悉 javascript 的人感到困惑.
The binding rules are quite different from most other OO languages which is why it seems to confuse a lot of people not familiar with javascript.
基本上,您在代码中使用 this
的方式和位置不会影响 this
的行为方式(无论它是独立函数、对象字面量等.) 决定 this
值的是你调用函数的方式.
Basically, how and where you use this
in the code does not affect how this
behaves (it does not matter if it's a standalone function, an object literal etc.) what determines the value of this
is how you call the function.
规则是:
1 - 当函数作为构造函数调用时,会创建一个新对象,并且 this
会绑定到该对象.例如:
1 - When a function is called as a constructor, a new object is created and this
is bound to that object. For example:
function Foo () {
this.bar = 1; // when called with the new keyword
// this refers to the object just created
}
new Foo().bar;
2 - 当作为对象方法调用时,this
指的是该方法所属的对象.基本上是最后一个点之前的名称.例如:
2 - When called as an object method this
refers to the object the method belongs to. Basically the name before the last dot. For example:
foo.bar = 1;
foo.baz = function () {
alert(this.bar); // this refers to foo when called as foo.baz()
}
foo.baz();
3 - 如果在任何函数之外使用或者如果函数没有作为方法调用 this
指的是全局对象.javascript 规范没有给全局对象命名,只是说存在一个,但对于浏览器,它传统上称为 window
.例如:
3 - If used outside of any function or if a function is not called as a method this
refers to the global object. The javascript spec doesn't give a name to the global object apart from saying that one exists but for browsers it is traditionally called window
. For example:
bar = 1;
alert(this.bar); // this refers to the global object
foo = {
bar: this.bar // also global object
}
function foofoo () {
alert(this.bar); // also refers to the global object
}
foofoo();
4 - 在事件处理程序(如 onclick 等)中,this
指的是触发事件的 DOM 元素.或者对于像 setTimeout
或 XMLHTTPRequest
这样与 DOM 无关的事件,this
指的是全局对象.例如:
4 - In an event handler (such as onclick etc.) this
refers to the DOM element that triggered the event. Or for events not associated with the DOM like setTimeout
or XMLHTTPRequest
, this
refers to the global object. For example:
foo.bar = 1;
foo.baz = function () {
alert(this.bar); // this would normally be foo but if this
// function is assigned to an event it would
// point to the element that triggered the event
}
somediv.bar = 2;
somediv.onclick = foo.baz; // clicking on somedive alerts 2 instead of 1
5 - 最后,当使用 call()
或 apply()
方法调用函数时 this
可以重新分配给任何东西(谷歌mdn function.prototype.call").这样,javascript中的任何对象都可以借用/窃取另一个对象的方法.例如:
5 - Finally, when a function is called using either the call()
or apply()
methods this
can be reassigned to anything whatsoever (google "mdn function.prototype.call"). In this way, any object in javascript can borrow/steal another objects' methods. For example:
cat = {
type: "cat",
explain: function () {
return "I am a " + this.type;
}
}
dog = {
type: "dog"
}
cat.explain.call(dog); // returns "I am a dog"
在现代 javascript 实现中使用 Function.bind()
我们现在有了另一条规则:
With Function.bind()
in modern javascript implementations we now have another rule:
6 - 函数还可以使用 bind()
方法将 this
显式绑定到对象.bind
方法返回函数的一个新实例,其中 this
绑定到传递给 bind
的参数.例如:
6 - Functions can also explicitly bind this
to an object using the bind()
method. The bind
method returns a new instance of the function where this
is bound to the argument passed to bind
. For example:
function explain () {
return "I am a " + this.type;
}
dog = {
type: "dog"
}
var dog_explain = explain.bind(dog);
dog_explain(); // returns "I am a dog"
ECMAscript 5 引入了严格模式,它改变了函数中 this 的含义,这些函数不是作为方法调用或通过 call 或 apply 调用的,因此我们必须添加一个新规则:
ECMAscript 5 introduced strict mode which changes the meaning of this in functions that isn't called as a method or called with call or apply so we have to add a new rule:
7 - 在严格模式下,this
不允许引用全局对象(浏览器中的窗口).因此,当一个函数没有作为方法调用或 this
没有通过 call
或 apply
或 bind<手动绑定到任何东西时/code> 然后
this
变成 undefined
:
7 - When in strict mode, this
isn't allowed to refer to the global object (window in browsers). So when a function is not called as a method or this
isn't bound to anything manually via call
or apply
or bind
then this
becomes undefined
:
"use strict";
function foo () {
return this;
}
foo(); // returns undefined instead of the global object
ECMAscript 6 引入了箭头函数.箭头函数通过提前绑定来改变 this 的行为方式.
ECMAscript 6 introduced arrow functions. Arrow functions change how this behaves by binding early.
8 - 在箭头函数中,this
在函数声明时被绑定.所以 this
在下面的代码中:
8 - In arrow functions, this
is bound at the time the function is declared. So this
in the following code:
var x = () => {return this};
就好像函数声明如下代码:
behaves as if the function is declared like the following code:
var x = function () {return this}.bind(this);
请注意,由于箭头函数中的 this
在函数声明时绑定如果要使用继承,则不能使用箭头函数.这是因为函数中的 this
将始终 指向父对象,而永远不会指向子对象.这意味着使用箭头函数进行继承的唯一方法是覆盖父对象中的所有箭头函数.
Note that since the this
in arrow functions are bound at the time the function is declared you can't use arrow functions if you want to use inheritance. That's because the this
in the function will always point to the parent object and will never point to the child object. That means that the only way to make inheritance work with arrow function is to override all arrow functions from the parent object.
相关文章