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

查看:26
本文介绍了“这个"是怎么来的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 元素.或者对于像 setTimeoutXMLHTTPRequest 这样与 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"

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

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 引入了严格模式,它改变了不是作为方法调用或通过 call 或 apply 调用的函数中 this 的含义,因此我们必须添加新规则:

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 没有通过 callapplybind<手动绑定到任何东西时/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 引入了箭头函数.箭头函数通过提前绑定来改变它的行为方式.

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.

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

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