“这个”怎么样? Javascript中的关键字在对象文字中起作用? [英] How does the "this" keyword in Javascript act within an object literal?

查看:126
本文介绍了“这个”怎么样? Javascript中的关键字在对象文字中起作用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我见过如何这个 ;关键字在函数中工作?,但我没有看到它回答以下内容。

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);

为什么前两次尝试失败,但最后两次失败?如果未绑定到当前对象文字, 绑定到什么?

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是一种后期绑定语言。事实上,这是非常晚的约束力。不仅这个在编译期间没有被绑定,它甚至在运行时都没有绑定(正如大多数其他后期绑定语言那样)。在javascript中,在通话时间内被绑定。

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.

基本上,你如何以及在哪里使用这个在代码中不影响这个的行为(如果它是一个独立的函数,一个对象文字等等无关紧要)什么决定这个就是你如何调用这个函数。

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 - 当一个函数作为构造函数调用时,会创建一个新对象,并且绑定到该对象。例如:

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 - 如果在任何函数之外使用或函数不是称为方法指的是全局对象。 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等)指的是触发事件的DOM元素。或者对于与DOM无关的事件,如 setTimeout XMLHTTPRequest 指的是全局对象。例如:

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 - 最后,当使用调用()调用函数时apply()方法 this 可以重新分配给任何东西(googlemdn 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"






更新:


Update:

在现代javascript实现中使用 Function.bind(),我们现在有了另一条规则:

With Function.bind() in modern javascript implementations we now have another rule:

6 - 函数也可以使用绑定将显式绑定到对象()方法。 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"






更多更新:


More update:

ECMAscript 5引入了严格模式,该模式在未被调用为方法或通过调用或应用调用的函数中更改此含义,因此我们必须添加新规则:

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 - 在严格模式下,不允许引用全局对象(浏览器中的窗口)。所以当一个函数没有被调用为方法或时,这个没有通过手动或<$手动绑定到任何东西c $ c> apply 或 bind 然后变为 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






甚至更新更新:


Even more update:

ECMAscript 6引入了箭头功能。箭头函数通过提前绑定来改变其行为方式。

ECMAscript 6 introduced arrow functions. Arrow functions change how this behaves by binding early.

8 - 在箭头函数中,在声明函数时被绑定。所以这个在以下代码中:

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.

这篇关于“这个”怎么样? Javascript中的关键字在对象文字中起作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆