Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/387.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 从回调函数和内联自调用函数访问父函数变量_Javascript - Fatal编程技术网

Javascript 从回调函数和内联自调用函数访问父函数变量

Javascript 从回调函数和内联自调用函数访问父函数变量,javascript,Javascript,我相信第一次看这两个自调用函数是一样的,唯一的区别是第一次我传递回调函数,然后通过arguments对象执行,而第二次我通过使函数自调用做同样的事情。现在来看访问父变量的要点,在第一个示例中,名称是“undefined”,而在第二个示例中,它是可访问的,并给出输出“Nishant”我无法理解它是如何工作的 (function(){ var name = "Nishant"; arguments[0](); })(function(){console.log(name);});

我相信第一次看这两个自调用函数是一样的,唯一的区别是第一次我传递回调函数,然后通过arguments对象执行,而第二次我通过使函数自调用做同样的事情。现在来看访问父变量的要点,在第一个示例中,名称是“
undefined
”,而在第二个示例中,它是可访问的,并给出输出“
Nishant
”我无法理解它是如何工作的

(function(){
    var name = "Nishant";
    arguments[0]();

})(function(){console.log(name);});
输出:(空字符串)

输出:Nishant

第一个版本中的“名称”指的是全局
窗口.name
属性*,第二个示例中通过闭包指的是私有var名称。
window.name
属性是可选的,默认为空字符串

如果这个属性不存在,您的第一个示例将抛出一个引用错误

闭包是在声明函数的作用域中创建的,而不是在调用它的时候。在第一个示例中,函数是在全局作用域中声明的,在第二个示例中是在包装器函数作用域中声明的

window.name = "NoClosure";
(function(){
    var name = "Closure";
    arguments[0](); 
})(function(){console.log(name);}); //>"NoClosure"

window.name = "NoClosure";
(function(){
    var name = "Closure";
    (function(){console.log(name);})(); //>"Closure"
})();
如果您使用
console.dir()
检查回调函数,您可以看到它没有闭包,如果您想自己测试它,这里有一个代码片段

(function wrapper(){
    var isPrivate = "A closure could see me";
    console.dir(arguments[0]);
})(function callback(){});
这里是另一个实验设置,有两个闭包,表明在函数调用中声明的函数能够得到闭包,但它始终是传递它的函数范围的闭包,它无法访问它作为参数传递给的函数的作用域,该函数后来作为回调调用它

(function outerScope(){
   var outerVar = "in outer scope";
   (function innerScope(cb){
       var innerVar = "in inner scope";
       cb();
   })(function callback(){
       console.log(
          "outer:"+ typeof outerVar,
          "inner:"+ typeof innerVar);
       console.dir(arguments.callee);
   })
})()
*来源

我不知道它是怎么工作的

(function(){
    var name = "Nishant";
    arguments[0]();

})(function(){console.log(name);});
JavaScript已经成功了。这意味着作用域由函数在源代码中的定义位置决定(与动态作用域不同,动态作用域是在运行时调用函数时确定的)

让我们为您的函数添加一些名称,以便我们可以更轻松地引用它们:

(function foo(){
    var name = "Nishant";
    arguments[0]();
})(function bar(){console.log(name);});
在这种情况下,
bar
是在
foo
之外定义的,因此无法访问
foo
内部定义的变量。事实上,在创建
bar
时,
foo
中的变量
name
甚至还不存在,因为
foo
尚未执行。
如果不内联定义,可能更容易看到:

function bar(){console.log(name);}

(function foo(){
    var name = "Nishant";
    arguments[0]();
})(bar);
这可能看起来更熟悉,我打赌你不会期望
name
inside
bar
name
inside
foo
有任何关系,对吧


在另一种情况下

(function foo(){
  var name = "Nishant";
  (function bar(){console.log(name);})()
})();

您在
foo
的内部定义了
bar
name
也在
foo
中,因此
bar
可以访问该变量(词法范围+闭包)。

Ref:当我们将回调函数作为参数传递给另一个函数时,回调函数是闭包,回调在包含函数体中的某个点执行,就像回调是在包含函数中定义的一样。这意味着回调本质上是一个闭包。阅读我的详细文章,轻松理解JavaScript闭包,了解闭包的更多信息。你能给我一个作为参数传递的回调函数的例子(或链接)吗?它传递给函数的闭包,因为我无法重现你描述的内容。好的,我已经阅读了这两篇文章,以及你对它的评论(这是您在这里所写内容的副本),但仍然未能遵循您的思路或重建任何回调结束的案例。如果我愿意,我的生活会轻松得多,因此请给我一个提示,说明您是如何设法让回调结束的。@Nishant:“当我们将回调函数作为参数传递给另一个函数时,回调函数就是闭包”。是的,这是真的,回调函数是闭包。但它只是“封闭”“定义它的环境。它与示例2中定义的闭包不同。您混淆了传递到函数中的参数是闭包这一事实意味着它与函数中定义的闭包相同。可以肯定的是,我引用了对提问者声明的任何评论。”“回调函数是闭包。当我们将回调函数作为参数传递给另一个函数时,回调函数会在包含函数体内的某个点执行,就像回调函数是在包含函数中定义的一样",因为他刚离开,没有回答我的问题。回调不可能通过闭包访问传递给他的函数的作用域?不可能。只有JS有动态作用域才可能,而JS没有。谢谢。哦,现在我终于可以不再觉得自己是个十足的白痴了。我尽我所能重建那个行为在询问者离开后,e提出了建议,但未能提出,并认为我会错过一些明显的东西。