我理解后者,我们在foo
对象上调用警报,该对象有另一个名为baz
的对象作为其属性,而该对象又有一个名为bar
的方法返回值x
。由于lexical scope
(我认为:)),JS编译器/解释器上升,在x
中找到baz
并返回1.
我的猜测是,当分配给变量go
然后从全局范围调用时,你得到3?只是想知道背景中发生了什么。任何帮助将不胜感激!!!
var x = 3;
var foo = {
x: 2,
baz: {
x: 1,
bar: function() {
return this.x;
}
}
}
var go = foo.baz.bar;
alert(go());
alert(foo.baz.bar());
答案 0 :(得分:7)
当你做这样的事情时:
var go = foo.baz.bar;
go();
在调用go
之前,您会发现foo.baz
已失去对bar()
的引用。它只是一个指向bar
函数的指针,并且与它所附加的对象没有任何关联。这意味着this
方法执行后foo.baz
将不会是bar
。
这明确是为.bind()
开发的内容。您可以像这样使用它:
var go = foo.baz.bar.bind(foo.baz);
go();
而且,它会对你有用。你也可以做同样的手动版本:
var go = function() {return foo.baz.bar();}
go();
但现在语言中已加入.bind()
以帮助您解决此类问题。
答案 1 :(得分:3)
首先,将函数表达式声明为名为go
的变量。如果执行函数go
this
引用全局对象,那么变量x
的值为3,这就是alert(go())
警告3的原因。另一方面,您执行方法foo.baz.bar()
。此处this
引用对象(foo
),x
引用值1
。因此它会提醒1
。
var x = 3;
var foo = {
x: 2,
baz: {
x: 1,
bar: function() {
return this.x;
}
}
}
//here you save a function expression
//to a variablewith name go
var go = foo.baz.bar;
//you execute go but this refer to the global object
//and x has the value of 3 in the global object
console.log(go());//this will output 3
//this refer to the object foo where x has
//the value of 1
console.log(foo.baz.bar());//this will output 3
答案 2 :(得分:2)
go-function在窗口中运行,foo.baz.bar-function在对象内运行。 这样做是为了让它返回内部x:
var go = function(){ return foo.baz.bar(); };
编辑: 一个好的经验法则:函数在它们声明的范围内运行。
在.toString()
中可以看到同样的事情Number(123).toString()
给出了与
不同的结果Number(456).toString()
即使调用相同的函数。
该函数实际上位于Number.prototype对象中。
答案 3 :(得分:0)
由于您正在将函数提取到变量中,您实际上将函数转移到全局范围,是的。
例如,如果您的对象栏也有函数foo(),并且您获取foo.baz.bar并且bar将包含return this.foo();这会错。 foo()不再存在,因为您只将该函数而不是它原来属于的对象赋给变量。如同,它不是参考。
答案 4 :(得分:0)
在这种情况下,它仅与执行上下文有关。函数总是相同的,唯一改变的是函数中'this'对象的含义。
您可以使用.apply()指定上下文,也可以使用.bind()强制永久强制特定上下文
您可以在我的代码版本中看到它:
var x = 3;
var foo = {
x: 2,
baz: {
x: 1,
bar: function() {
return this.x;
}
}
}
var go = foo.baz.bar;
alert(go.apply(this));
alert(go.apply(foo));
alert(go.apply(foo.baz));
var goBinded = foo.baz.bar.bind(foo.baz);
alert(goBinded());
alert(goBinded.apply(foo));