Javascript 嵌套。绑定未按预期工作
不幸的是,Javascript 嵌套。绑定未按预期工作,javascript,closures,call,bind,nested-function,Javascript,Closures,Call,Bind,Nested Function,不幸的是,.bind在创建更复杂的闭包时让我很难过 我对其中的原因很感兴趣。一旦嵌套函数,绑定的工作方式似乎就不同了 例如: function t(){ t = t.bind({}); //correctly assigns *this* to t function nested_t(){ nested_t = nested_t.bind({}); // fails to assign *this* to nested_t return nes
.bind
在创建更复杂的闭包时让我很难过
我对其中的原因很感兴趣。一旦嵌套函数,绑定的工作方式似乎就不同了
例如:
function t(){
t = t.bind({}); //correctly assigns *this* to t
function nested_t(){
nested_t = nested_t.bind({}); // fails to assign *this* to nested_t
return nested_t;
}
return nested_t();
}
//CASE ONE
alert(t());
// alerts the whole function t instead of nested_t
//CASE TWO
aleft(t.call(t));
// alerts the global object (window)
在这两种情况下,我都希望出现这样的行为:
function t(){
var nested_t = function nested_t(){
return this;
};
return nested_t.call(nested_t);
}
alert(t.call(t));
如果有人能在第一种(和/或)第二种情况下解释
.bind
的行为,我们将不胜感激 因此,我在这里并不是完全重复您的问题(两种情况都返回全局对象),但我将尝试解释我看到的代码
function t(){
t = t.bind({}); //correctly assigns *this* to t
function nested_t(){
nested_t = nested_t.bind({}); // fails to assign *this* to nested_t
return this;
}
return nested_t();
}
//CASE ONE
alert(t());
让我们一步一步来
首先,定义函数t()
。然后,在调用时,它会被一个干净的上下文覆盖。然而,我看不到这个上下文的任何用法
现在,定义了一个嵌套函数(nested\t
)。调用时,它会被干净的上下文覆盖。然后返回调用它时的上下文
返回到t()
。然后返回nested_t()
,而不是nested_t
本身的结果。在原始函数调用中,nested\u t
仍在使用全局上下文调用
因此,当您运行
t()
时,它将返回全局对象。因此,我并不是在这里完全重复您的问题(两种情况都返回全局对象),但我将尝试解释我看到的代码
function t(){
t = t.bind({}); //correctly assigns *this* to t
function nested_t(){
nested_t = nested_t.bind({}); // fails to assign *this* to nested_t
return this;
}
return nested_t();
}
//CASE ONE
alert(t());
让我们一步一步来
首先,定义函数t()
。然后,在调用时,它会被一个干净的上下文覆盖。然而,我看不到这个上下文的任何用法
现在,定义了一个嵌套函数(nested\t
)。调用时,它会被干净的上下文覆盖。然后返回调用它时的上下文
返回到t()
。然后返回nested_t()
,而不是nested_t
本身的结果。在原始函数调用中,nested\u t
仍在使用全局上下文调用
因此,当您运行t()
时,它将返回全局对象。您的代码是如何工作的
现在还不清楚你的代码在做什么。您可以找到.bind()
的文档。看起来您可能不知何故误解了此是什么以及如何使用它。无论如何,运行代码时会发生以下情况:
t
函数t
函数。
t
被替换为新值(原始t
绑定到特定上下文-匿名空对象),该值不会以任何方式影响当前调用。此外,当全局t
被覆盖时,本地t
表现为只读。您可以通过尝试以下代码来检查它:(函数foo(){return(函数栏(){bar=window.bar='baz';返回栏;}();})(
)并将返回值与window.bar
进行比较嵌套\u t
也会发生同样的情况nested_t
返回调用它时使用的上下文,即窗口
,因为没有指定上下文。具体来说,它不是用空对象上下文调用的,因为内部的.bind()
不会影响调用本身t
,将其本身作为上下文。由于t
在其代码中的任何地方都不使用上下文(this
),因此实际上没有任何变化你的误解是什么 基本上,你混淆了两件事——函数实例和函数调用上下文。函数在JavaScript中是“一等公民”——它是一个对象,您可以为其属性赋值
function foo () {
foo.property = 'value';
}
foo(); // foo.property is assigned a value
这与函数调用上下文无关。调用函数时,会为该调用指定一个上下文,可以使用此(函数体内部)访问该上下文
使用.bind()
时,只需使用相同的代码创建一个新函数,该函数锁定到特定上下文
function foo () {
this.property = 'value';
}
var fixedContext = {},
object = {};
bar = foo.bind(fixedContext);
foo.call(object); // fixedContext.property is set instead of object.property
但在这种情况下,也有函数实例foo
和bar
,它们也可以被分配属性,与这些函数的调用上下文无关。代码的工作方式
现在还不清楚你的代码在做什么。您可以找到.bind()
的文档。看起来您可能不知何故误解了此
是什么以及如何使用它。无论如何,运行代码时会发生以下情况:
在全局范围内创建t
函数
[案例一]调用t
函数。
全局范围t
被替换为新值(原始t
绑定到特定上下文-匿名空对象),该值不会以任何方式影响当前调用。此外,当全局t
被覆盖时,本地t
表现为只读。您可以通过尝试以下代码来检查它:(函数foo(){return(函数栏(){bar=window.bar='baz';返回栏;}();})(
)并将返回值与window.bar
进行比较
在嵌套上下文(而不是全局上下文)中的嵌套\u t
也会发生同样的情况
返回嵌套调用的结果nested_t
返回调用它时使用的上下文,即窗口
,因为没有指定上下文。具体来说,它不是用空对象上下文调用的,因为内部的.bind()
不会影响调用本身
[案例二]同样的事情再次发生。现在您只需调用t
,其本身就是
var foo = function() { return this.x; };
alert(foo()); // undefined
alert(foo.bind({x: 42})()); // 42
var bar = function() { return foo.bind(this)(); };
alert(bar()); // undefined
alert(bar.bind({x: 42})());