了解 javascript 中的本地和全局变量
understanding LOCAL and GLOBAL variables in javascript
我为随机数组编写了这段代码:
function shuffle(arr) {
for (i = 0; i < arr.length; i++) {
x = Math.floor(Math.random() * arr.length);
y = Math.floor(Math.random() * arr.length);
if (x === y) { //for dont change arr[i] with arr[i]!!!
continue;
}
temp0 = arr[x];
arr[x] = arr[y];
arr[y] = temp0;
}
return arr
}
它工作正常。
但我的问题是,这个函数不是全局的,我用一个例子来解释它:
sampleArray=["a", "b", "c", "d"];
shuffle(sampleArray); //only run function
console.log (sampleArray); // output NOT shuffled. ==>> ["a", "b", "c", "d"]
console.log (shuffle(sampleArray)); //output shuffled. my be ["d", "a", "c", "b"] or ...
在主代码中我无法声明嵌套在 shuffle 函数中的 sampleArray...
let
、const
和 var
上下文
如果您没有使用 let
、const
或 var
定义变量,它们将被限定为全局变量。
您在 here 中有一个关于 javascript 变量和作用域的很好的教程。
但正在恢复:
- 如果您不在变量定义前添加
let
、const
或 var
,将始终创建为全局变量。
- 如果您之前使用
var
,变量将被创建为函数作用域。
- 如果您之前使用
let
,变量将是块范围的(在两个 {} 之间)。
- 如果您之前使用
const
,则应用与 let
相同的规则,但您不能为变量重新分配新值。
还有!
在 javascript 中,数组等非允许值作为引用传递给函数,这意味着如果您在函数内更改任何数组值,原始变量的值也会更改 (有关更多信息,check 此 link)。这就是您的 sampleArray
被更改的原因:因为您更改了 arr
变量,该变量引用 shuffle
函数中的 sampleArray
。
示例时间!
要实现此功能,您可以在 shuffle
函数中执行 arr
的 deepcopy,如下所示:
function shuffle(arr) {
//deep copy
const deepCopyArray = JSON.parse(JSON.stringify(arr));
for (i = 0; i < deepCopyArray.length; i++) {
x = Math.floor(Math.random() * deepCopyArray.length);
y = Math.floor(Math.random() * deepCopyArray.length);
if (x === y) { //for dont change arr[i] with arr[i]!!!
continue;
}
temp0 = deepCopyArray[x];
deepCopyArray[x] = deepCopyArray[y];
deepCopyArray[y] = temp0;
}
return deepCopyArray
}
sampleArray=["a", "b", "c", "d"];
shuffle(sampleArray); //only run function
console.log (sampleArray); // output NOT shuffled. ==>> ["a", "b", "c", "d"]
console.log (shuffle(sampleArray)); //output shuffled. my be ["d", "a", "c", "b"]
您的代码中有错字。长度不长。此外,由于数组是通过引用传递的,因此您不需要 return
function shuffle(arr) {
for (i = 0; i < arr.length; i++) {
var x = Math.floor(Math.random() * arr.length);
var y = Math.floor(Math.random() * arr.length);
if (x === y) { //for dont change arr[i] with arr[i]!!!
continue;
}
temp0 = arr[x];
arr[x] = arr[y];
arr[y] = temp0;
}
}
sampleArray=["a", "b", "c", "d"];
shuffle(sampleArray);
console.log(sampleArray);
我为随机数组编写了这段代码:
function shuffle(arr) {
for (i = 0; i < arr.length; i++) {
x = Math.floor(Math.random() * arr.length);
y = Math.floor(Math.random() * arr.length);
if (x === y) { //for dont change arr[i] with arr[i]!!!
continue;
}
temp0 = arr[x];
arr[x] = arr[y];
arr[y] = temp0;
}
return arr
}
它工作正常。 但我的问题是,这个函数不是全局的,我用一个例子来解释它:
sampleArray=["a", "b", "c", "d"];
shuffle(sampleArray); //only run function
console.log (sampleArray); // output NOT shuffled. ==>> ["a", "b", "c", "d"]
console.log (shuffle(sampleArray)); //output shuffled. my be ["d", "a", "c", "b"] or ...
在主代码中我无法声明嵌套在 shuffle 函数中的 sampleArray...
let
、const
和 var
上下文
如果您没有使用 let
、const
或 var
定义变量,它们将被限定为全局变量。
您在 here 中有一个关于 javascript 变量和作用域的很好的教程。
但正在恢复:
- 如果您不在变量定义前添加
let
、const
或var
,将始终创建为全局变量。 - 如果您之前使用
var
,变量将被创建为函数作用域。 - 如果您之前使用
let
,变量将是块范围的(在两个 {} 之间)。 - 如果您之前使用
const
,则应用与let
相同的规则,但您不能为变量重新分配新值。
还有!
在 javascript 中,数组等非允许值作为引用传递给函数,这意味着如果您在函数内更改任何数组值,原始变量的值也会更改 (有关更多信息,check 此 link)。这就是您的 sampleArray
被更改的原因:因为您更改了 arr
变量,该变量引用 shuffle
函数中的 sampleArray
。
示例时间!
要实现此功能,您可以在 shuffle
函数中执行 arr
的 deepcopy,如下所示:
function shuffle(arr) {
//deep copy
const deepCopyArray = JSON.parse(JSON.stringify(arr));
for (i = 0; i < deepCopyArray.length; i++) {
x = Math.floor(Math.random() * deepCopyArray.length);
y = Math.floor(Math.random() * deepCopyArray.length);
if (x === y) { //for dont change arr[i] with arr[i]!!!
continue;
}
temp0 = deepCopyArray[x];
deepCopyArray[x] = deepCopyArray[y];
deepCopyArray[y] = temp0;
}
return deepCopyArray
}
sampleArray=["a", "b", "c", "d"];
shuffle(sampleArray); //only run function
console.log (sampleArray); // output NOT shuffled. ==>> ["a", "b", "c", "d"]
console.log (shuffle(sampleArray)); //output shuffled. my be ["d", "a", "c", "b"]
您的代码中有错字。长度不长。此外,由于数组是通过引用传递的,因此您不需要 return
function shuffle(arr) {
for (i = 0; i < arr.length; i++) {
var x = Math.floor(Math.random() * arr.length);
var y = Math.floor(Math.random() * arr.length);
if (x === y) { //for dont change arr[i] with arr[i]!!!
continue;
}
temp0 = arr[x];
arr[x] = arr[y];
arr[y] = temp0;
}
}
sampleArray=["a", "b", "c", "d"];
shuffle(sampleArray);
console.log(sampleArray);