当前位置: 首页 > 知识库问答 >
问题:

Javascript中的“this”关键字如何在对象文本中起作用?[副本]

万英武
2023-03-14

我已经看到了“this”关键字在函数中是如何工作的?,但我没有看到它回答了下面的问题。

给定此代码:

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未绑定到当前对象文字,那么它绑定到什么?

共有1个答案

温翔宇
2023-03-14

Javascript是一种较晚的绑定语言。其实是很晚的绑定。this不仅在编译时不绑定,甚至在运行时也不绑定(与大多数其他后期绑定语言一样)。在javascript中,this是在调用期间绑定的。

绑定规则与大多数其他OO语言有很大的不同,这就是为什么它似乎让许多不熟悉JavaScript的人感到困惑的原因。

基本上,在代码中如何和在哪里使用this并不影响this的行为(如果它是独立函数、对象文字等也不重要),决定this值的是如何调用函数。

这些规则是:

1-当函数作为构造函数调用时,将创建一个新对象,并将this绑定到该对象。例如:

function Foo () {
    this.bar = 1; // when called with the new keyword
                  // this refers to the object just created
}
new Foo().bar;

2-作为对象方法调用时,this引用该方法所属的对象。基本上是最后一个点之前的名字。例如:

foo.bar = 1;
foo.baz = function () {
    alert(this.bar); // this refers to foo when called as foo.baz()
}
foo.baz();

3-如果在任何函数之外使用,或者如果函数未作为方法调用this引用全局对象。javascript规范除了说明全局对象存在之外,并没有给它起名字,但对于浏览器来说,它通常被称为window。例如:

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元素。或者对于与DOM没有关联的事件(如settimeoutXMLHttpRequest),this引用全局对象。例如:

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()方法调用函数时,这个可以重新分配给任何东西(google“MDN function.prototype.call”)。这样,javascript中的任何对象都可以借用/窃取另一个对象的方法。例如:

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(),我们现在有了另一个规则:

6-函数还可以使用bind()方法将this显式绑定到对象。bind方法返回函数的新实例,其中this绑定到传递给bind的参数。例如:

function explain () {
    return "I am a " + this.type;
}
dog = {
    type: "dog"
}
var dog_explain = explain.bind(dog);
dog_explain(); // returns "I am a dog"

ECMAScript5引入了严格模式,它改变了不作为方法调用的函数、不通过调用或应用调用的函数中严格模式的含义,因此我们必须添加一个新规则:

7-在严格模式下,this不允许引用全局对象(浏览器中的窗口)。因此,当函数未作为方法调用或this未通过callapplybind手动绑定到任何东西时,则this变为undefined:

"use strict";
function foo () {
    return this;
}
foo(); // returns undefined instead of the global object

ECMAScript6引入了箭头函数。箭头函数通过早期绑定来改变其行为。

8-在箭头函数中,this在声明函数时绑定。因此在以下代码中this:

var x = () => {return this};

该函数的行为类似于如下代码声明的函数:

var x = function () {return this}.bind(this);

注意,由于箭头函数中的this是在函数声明时绑定的,所以如果要使用继承,就不能使用箭头函数。那是因为函数中的this将始终指向父对象,而永远不会指向子对象。这意味着使继承与箭头函数一起工作的唯一方法是从父对象重写所有箭头函数。

 类似资料:
  • 问题内容: 我已经看到“ this”关键字在函数中如何工作?,但我看不到它能回答以下问题。 给出以下代码: 为什么前两次尝试失败,而后两次尝试成功?如果没有绑定到当前对象的文字,什么是它必然? 问题答案: Javascript是一种后期绑定语言。实际上,绑定很晚。不仅在编译时没有绑定,甚至在运行时也没有绑定(就像大多数其他后期绑定语言一样)。在javascript中,是在通话期间绑定的。 绑定规则

  • 本文向大家介绍“ this”关键字在JavaScript中如何工作?,包括了“ this”关键字在JavaScript中如何工作?的使用技巧和注意事项,需要的朋友参考一下 在JavaScript中,此关键字用作引用,以引用执行的代码的对象或主题。 示例

  • 问题内容: “ this”关键字如何工作? 问题答案: [§11.1.1]的关键字 所述关键字的计算结果为当前执行上下文的ThisBinding的值 这个绑定是JavaScript解释器在评估JavaScript代码时所维护的,例如特殊的CPU寄存器,其中包含对对象的引用。每当在以下三种情况之一中建立执行上下文时,解释器都会更新ThisBinding: 1.初始全局执行上下文 在顶级代码中评估的J

  • 这到底是什么类型的?

  • 我是JavaScript的新手,我认为对象是通过引用传递的。 我期望的输出是: 获得的输出: 当引用的地址时,为什么仍然 null null

  • 问题内容: 为什么下面的工作? 而这不起作用: 更清楚地说:目前,我无法将CSS属性作为变量传递给animate函数。 问题答案: 是有效的对象文字。该代码将创建一个对象,其属性名为,值为10。以下两项相同: 在ES5及更早版本中,不能在对象文字中使用变量作为属性名称。您唯一的选择是执行以下操作: ES6 将 _ComputedPropertyName_定义为对象文字语法的一部分,这使您可以编写如