Javascript 闭合混淆
我对这件事有些困惑。下面我有两个独立的代码,看起来很相似,但它们的输出不同Javascript 闭合混淆,javascript,Javascript,我对这件事有些困惑。下面我有两个独立的代码,看起来很相似,但它们的输出不同 function setup(x) { var array = []; for(var i=0;i<arguments.length;i++){ array[i]= arguments[i]; } return array; } console.log(setup('a','b')); // will output ["a","b"] -------------- function f() { var
function setup(x) {
var array = [];
for(var i=0;i<arguments.length;i++){
array[i]= arguments[i];
}
return array;
}
console.log(setup('a','b')); // will output ["a","b"]
--------------
function f() {
var i, array = [];
for(i = 0; i < 3; i++) {
array[i] = function(){
return i;
}
}
return array;
}
var a = f();
console.log(a()); //output: [function(),function(),function()]
console.log(a[0]()); //output: 3 //same output in a[1]() and a[2]() calls as well
功能设置(x){
var数组=[];
对于(var i=0;i在第二个示例中,您正在循环中创建3
函数,但所有函数都在相同的变量范围内创建,因此它们都引用并返回相同i
变量的值
因此,从函数返回的i
值表示调用函数时的值。因为您在循环后调用它们,i
的值是3
,所以这是返回的值
这就是闭包的意思。函数“关闭”了创建它们的变量范围中存在的变量。它们不关闭变量的值,而是关闭变量本身,因此它们总是获取变量的当前状态
要使每个函数引用不同的i
,每个函数都需要在一个单独的变量范围内创建,该变量范围有自己独特的i
function f() {
var i, array = [];
for (i = 0; i < 3; i++) {
// The extra parentheses around the function are unnecessary here.
// But this is more idiomatic, as it shares syntax with how function
// expressions are introduced in statements.
// I.e. you could just copy-paste it anywhere.
array[i] = (function () {
return i;
})(); // don't rely on automatic semicolon insertion
}
return array;
}
因为在JavaScript中创建新变量作用域的唯一方法是调用函数,所以需要在新函数调用中创建每个函数
function makeFunction(j) {
return function(){
return j;
};
}
function f() {
var i, array = [];
for(i = 0; i < 3; i++) {
array[i] = makeFunction(i);
}
return array;
}
函数makeFunction(j){
返回函数(){
返回j;
};
}
函数f(){
变量i,数组=[];
对于(i=0;i<3;i++){
数组[i]=makeFunction(i);
}
返回数组;
}
因此,我在这里创建了一个名为makeFunction
的新函数。它接收单个参数,并返回一个引用并返回该参数的新函数
由于每次调用makeFunction
都会创建一个新的、唯一的变量范围,因此返回的每个函数都将引用自己唯一的j
变量,因此将返回调用makeFunction
时存在的j
值(除非您的函数修改了j
,如果您愿意,它可以这样做)
请注意,为了清晰起见,我使用了变量名j
。您也可以使用I
或其他名称。在第二个示例中,您在循环中创建3
函数,但所有函数都在相同的变量范围内创建,因此它们都引用并返回相同I
变量的值
因此,从函数返回的i
值表示调用函数时的值。因为您在循环后调用它们,i
的值是3
,所以这是返回的值
这就是闭包的意思。函数“关闭”了创建它们的变量范围中存在的变量。它们不关闭变量的值,而是关闭变量本身,因此它们总是获取变量的当前状态
要使每个函数引用不同的i
,每个函数都需要在一个单独的变量范围内创建,该变量范围有自己独特的i
function f() {
var i, array = [];
for (i = 0; i < 3; i++) {
// The extra parentheses around the function are unnecessary here.
// But this is more idiomatic, as it shares syntax with how function
// expressions are introduced in statements.
// I.e. you could just copy-paste it anywhere.
array[i] = (function () {
return i;
})(); // don't rely on automatic semicolon insertion
}
return array;
}
因为在JavaScript中创建新变量作用域的唯一方法是调用函数,所以需要在新函数调用中创建每个函数
function makeFunction(j) {
return function(){
return j;
};
}
function f() {
var i, array = [];
for(i = 0; i < 3; i++) {
array[i] = makeFunction(i);
}
return array;
}
函数makeFunction(j){
返回函数(){
返回j;
};
}
函数f(){
变量i,数组=[];
对于(i=0;i<3;i++){
数组[i]=makeFunction(i);
}
返回数组;
}
因此,我在这里创建了一个名为makeFunction
的新函数。它接收单个参数,并返回一个引用并返回该参数的新函数
由于每次调用makeFunction
都会创建一个新的、唯一的变量范围,因此返回的每个函数都将引用自己唯一的j
变量,因此将返回调用makeFunction
时存在的j
值(除非您的函数修改了j
,如果您愿意,它可以这样做)
请注意,为了清晰起见,我使用了变量名j
。您也可以使用I
或其他名称。在JavaScript中,您有函数语句和函数表达式。第一个声明命名函数,后一个求值为命名或匿名函数。您使用的是函数表达式
我认为您需要做的是调用表达式。您需要做的就是立即调用返回I
的函数
function f() {
var i, array = [];
for (i = 0; i < 3; i++) {
// The extra parentheses around the function are unnecessary here.
// But this is more idiomatic, as it shares syntax with how function
// expressions are introduced in statements.
// I.e. you could just copy-paste it anywhere.
array[i] = (function () {
return i;
})(); // don't rely on automatic semicolon insertion
}
return array;
}
但是,下一个示例是错误的,因为即使在for
块中声明了n
,它也会像是在函数顶部声明的一样,只在for
块中初始化。记住,这是JavaScript,不是Java,不是C,不是C,不是:
函数f(){
变量i,数组=[];
对于(i=0;i<3;i++){
var n=i;
数组[i]=函数(){
返回n;
};
}
返回数组;
}
等效代码:
function f() {
var i, array = [];
var n;
for (i = 0; i < 3; i++) {
n = i;
array[i] = function () {
return n;
};
}
return array;
}
函数f(){
变量i,数组=[];
var n;
对于(i=0;i<3;i++){
n=i;
数组[i]=函数(){
返回n;
};
}
返回数组;
}
在JavaScript中,有函数语句和函数表达式。第一个声明命名函数,后一个求值为命名函数或匿名函数。您使用的是函数表达式
我认为您需要做的是调用表达式。您需要做的就是立即调用返回I
的函数
function f() {
var i, array = [];
for (i = 0; i < 3; i++) {
// The extra parentheses around the function are unnecessary here.
// But this is more idiomatic, as it shares syntax with how function
// expressions are introduced in statements.
// I.e. you could just copy-paste it anywhere.
array[i] = (function () {
return i;
})(); // don't rely on automatic semicolon insertion
}
return array;
}
但是,下一个示例是错误的,因为即使在for
块中声明了n
,它也会像是在函数顶部声明的一样,只在for
块中初始化。记住,这是JavaScript,不是Java,不是C,不是C,不是C,不是