JavaScript允许被调用函数访问调用函数变量
如果我在函数中定义了一个内部函数,则内部函数可以访问外部函数的变量。如果我希望这个内部函数是可重用的,并在外部函数之外定义它,那么内部函数现在就失去了对外部函数变量的访问权。如何使这个新的可重用内部函数能够访问外部函数变量,而不将这些变量作为参数传入JavaScript允许被调用函数访问调用函数变量,javascript,scope,closures,Javascript,Scope,Closures,如果我在函数中定义了一个内部函数,则内部函数可以访问外部函数的变量。如果我希望这个内部函数是可重用的,并在外部函数之外定义它,那么内部函数现在就失去了对外部函数变量的访问权。如何使这个新的可重用内部函数能够访问外部函数变量,而不将这些变量作为参数传入 function a () { var x = [[1,2,3], [1,2,3], [1,2,3]]; var keys = Object.keys(x[0]); for (v
function a () {
var x = [[1,2,3], [1,2,3], [1,2,3]];
var keys = Object.keys(x[0]);
for (var i = 0; i < x.length; i++) {
angular.forEach(keys, loop);
}
}
function loop (key) {
console.log(key, i);//i is undefined here
}
a();
函数a(){
var x=[[1,2,3],[1,2,3],[1,2,3];
var keys=Object.keys(x[0]);
对于(变量i=0;i
具体来说,有没有一种方法不需要1)为其分配变量,2)不需要将变量作为参数传递,3)不需要创建全局变量
编辑:似乎没有办法做到这一点。但是如果我尝试另一种方法,让可重用函数返回一个新函数,我也无法访问内部作用域。为什么会这样?有什么办法可以让它发挥作用吗
function a () {
var x = [[1,2,3], [1,2,3], [1,2,3]];
var keys = Object.keys(x[0]);
var myloop = loop();
for (var i = 0; i < x.length; i++) {
angular.forEach(keys, myloop);
}
}
function loop (key) {
return function(key) {
console.log(key, i);//i is undefined here
};
}
a();
函数a(){
var x=[[1,2,3],[1,2,3],[1,2,3];
var keys=Object.keys(x[0]);
var myloop=loop();
对于(变量i=0;i
内部函数由外部函数局部处理。因此,您可以从内部函数访问属于外部函数的变量。但是,一旦您将内部函数作为外部函数之外的单独函数,那么您就不再能够访问外部函数的私有数据变量
如果这看起来很复杂,下面是一个例子:
function A
{
//variables
function B
{
can use variables of A
}
}
但是,
在JS(和许多其他语言)中,存在可见性上下文。可能的上下文是“全局”或函数或块。这些上下文是分层的,内部可以读取外部。外部永远不能读取内部(封装原则),除非内部将变量声明为全局变量
如何使这个新的可重用内部函数能够访问外部函数变量,而不将这些变量作为参数传入
function a () {
var x = [[1,2,3], [1,2,3], [1,2,3]];
var keys = Object.keys(x[0]);
for (var i = 0; i < x.length; i++) {
angular.forEach(keys, loop);
}
}
function loop (key) {
console.log(key, i);//i is undefined here
}
a();
你不能。JavaScript具有动态范围,而不是动态范围
另请参见:在下面的示例中,
循环
返回一个函数,该函数关闭在i
的值之上
function a () {
var x = [[1,2,3], [1,2,3], [1,2,3]];
var keys = Object.keys(x[0]);
for (var i = 0; i < keys.length; i++) {
keys.forEach(loop(i));
}
}
function loop (i) {
return function (key) {
console.log(key, i); // i is now defined
}
}
a();
我还想让大家知道我刚刚发现的另一个选择。如果使用.bind,则可以将函数与i进行curry,其他变量将在curry参数之后传入
....
angular.forEach(keys, loop.bind(null, i));
...
function loop(i, key) {
...
}
虽然不推荐使用全局变量,但也可以使用全局变量。除了使用全局变量,还有其他方法吗?我认为闭包一定有办法,但我无法让它工作。让一个可重用函数依赖于其作用域之外的变量对我来说是一个非常糟糕的主意。将
i
传递到函数中有什么问题?问题是您需要创建一个匿名函数来完成此操作。forEach(key,function(key){loop(key,i)})这个函数应该完成什么?因此keys
包含x
中第一个数组的键(或索引值)。然后在a
的长度上迭代(函数的长度为零,因此循环永远不会运行),如果循环以某种方式执行,则再次循环键。你能澄清一下吗?这是最接近的解决方案,因此请将其标记为正确。
....
angular.forEach(keys, loop.bind(null, i));
...
function loop(i, key) {
...
}