Javascript [this]关键字与new绑定

Javascript [this] keyword binding with new

本问题已经有最佳答案,请猛点这里访问。

在阅读你不知道JS的书时:这个& 对象原型

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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

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


当你调用这个obj1.foo( 2 )时,执行obj1的方法作为参数传递2.当执行foo时,为调用对象定义一个名为a的属性,并为其赋值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 = {}。如果您执行以下操作:

1
obj.a

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

1
obj.a = 4;

你做两件事,你定义属性a并为它分配一个值。


因为任何函数都可以是构造函数。想象一下,如果你自己使用foo

1
var obj3 = new foo(3);

你期望得到一个类似{ a: 3 }的对象,对吗?

即使该功能附加到其他内容,这仍然有效。每次使用new时,都会创建一个新对象,而不是更改现有对象。

在第一个实例中,您将该函数用作方法:

1
obj1.foo(2);

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


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

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

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