Javascript[this]关键字与new绑定

Javascript [this] keyword binding with new

看书的时候You Don't Know JS: this & Object Prototypes

我找到了这个关于 this 绑定的例子:

function foo(something) {
  this.a = something;
}

var obj1 = {
 foo: foo
};

var obj2 = {};

obj1.foo( 2 );
console.log( obj1.a ); // 2

obj1.foo.call( obj2, 3 );
console.log( obj2.a ); // 3

var bar = new obj1.foo( 4 );
console.log( obj1.a ); // 2
console.log( bar.a ); // 4

我不明白为什么在执行 new obj1.foo(4) console.log(obj1.a) 后打印 2 而不是 4。如果我注释行 obj1.foo(2) 上面日志的结果是 undefined.

因为任何函数都可以是构造函数。想象一下,如果您单独使用 foo

var obj3 = new foo(3);

您也希望得到类似的对象{ a: 3 },对吗?

即使函数附加到其他东西,这仍然有效。每次使用 new 时,您都是在创建一个新对象,而不是更改现有对象。

首先,您将函数用作方法:

obj1.foo(2);

在这种情况下,上下文设置为 obj1 因为它是调用它的那个。但是当您使用 new 时,会创建一个全新的对象并将该新对象用作上下文。

当您调用此 obj1.foo( 2 ) 时,您执行 obj1 的方法,将 2 作为参数传递。当执行 foo 时,定义了一个名为 [=15] 的 属性 =] 到 calling 对象,并为其分配值 something,在本例中为 2。本例中的 calling 对象是 obj1。因此,出于这个原因,obj1 获取了一个名为 a 的 属性,其值为 2.

And if I comment the line : obj1.foo(2) the result of the log above is undefined.

发生这种情况是因为如果您评论您提到的行。 obj1 没有获得 属性 a。因此 a 在这种情况下是未定义的。一般来说,如果我们考虑一个空对象objobj = {}。如果您执行以下操作:

obj.a

您在对象 obj 上定义了一个名为 a 的 属性。此外,如果您执行以下操作:

obj.a = 4;

你做了两件事,你定义了 属性 a 并给它赋值。

所以,让我们把它分解成更小的步骤。

首先,obj1.foo 调用 foo 函数。 foo 函数接受一个参数并将该参数分配给调用 foo 的对象的 a 键(它比这要复杂一点,如果你愿意,我可以在后面详细说明)。

所以当你调用obj1.foo(2)时,你是在调用foo方法,通过obj1对象的角度传入参数2。这就是 obj1.a 等于 2 的原因。 由于这是为 obj1.a 赋值的命令,因此省略该调用将导致 obj1.a 未定义。