简体   繁体   English

在Javascript中引用数组

[英]Referencing Arrays in Javascript

I've got what may be a stupid question. 我有一个可能是个愚蠢的问题。 In the code below, the function doStuff appears to reassign myArray to an empty array, but when tried it in the console, myArray is still [2,3,4,5]. 在下面的代码中,函数doStuff似乎将myArray重新分配给一个空数组,但是当在控制台中尝试它时,myArray仍然是[2,3,4,5]。

var myArray = [2, 3, 4, 5];
function doStuff(arr) {
   arr = [];
};

doStuff(myArray);
console.log(myArray)// => [2,3,4,5]

Further, a function that modifies the array seems to work fine. 此外, 修改数组的函数似乎工作正常。 For example: 例如:

 function changeSecondIndex(arr){
      arr[2] = 25;
 }

 changeSecondIndex(myArray)
 console.log(myArray) // => [2,3,25,5]

Could someone please help me understand what's going on here? 有人可以帮我理解这里发生了什么吗? Thanks. 谢谢。

Your code is creating new empty array, instead you can empty existing array with length = 0 您的代码正在创建新的空数组,而是可以清空length = 0现有数组

 var myArray = [2, 3, 4, 5]; function doStuff(arr) { arr.length = 0; }; doStuff(myArray); console.log(myArray) 

Javacript arrays are passed by reference , which means they can be modified within functions. Javacript数组通过引用传递 ,这意味着它们可以在函数内修改。 This is why your second code snippet works. 这就是您的第二个代码段有效的原因。

Your first code snippet, however, simply declares a new variable arr within the scope of the function. 但是,您的第一个代码片段只是在函数范围内声明了一个变量arr It does not overwrite the old variable name, it merely removes your ability to reference the global variable you passed in. 它不会覆盖旧的变量名,它只会删除您引用传入的全局变量的能力。

Once that function exits, the new variable arr goes out of scope, and the name binding falls back to the global variable you declared previously. 该函数退出后,新变量arr超出范围,名称绑定将回退到您之前声明的全局变量。

That's why doStuff() does not modify the original array - because you were actually declaring a brand new array that just happened to share the same name within the scope of the function. 这就是为什么doStuff()不会修改原始数组的原因 - 因为你实际上声明了一个刚刚在函数范围内共享相同名称的全新数组。

Arrays are passed by reference in JavaScript. 数组通过JavaScript 引用传递。 So, in your doStuff and changeSecondIndex functions, the arr parameter contains a reference to myArray . 因此,在doStuffchangeSecondIndex函数中, arr参数包含对myArray引用

In changeSecondIndex , you're using that reference to access and update a property of the array. changeSecondIndex ,您正在使用该引用来访问和更新数组的属性。 That works fine, as you can see. 你可以看到,这很好。 But in doStuff , what's actually happening is that you are setting arr to a new array. 但是在doStuff ,实际发生的是你将arr设置为一个新数组。 What that does is remove the fact that arr was a reference to myArray and sets it to a new blank array. 这样做是为了删除arr是对myArray的引用并将其设置为新的空白数组的事实。 That's why myArray is not modified. 这就是myArray未被修改的原因。

Objects are passed by reference in JavaScript, when you call the function in your first example the parameter arr is a reference to the object that is passed when the function is invoked 对象在JavaScript中通过引用传递,当您在第一个示例中调用该函数时,参数arr是对调用该函数时传递的对象的引用

var myArray = [2, 3, 4, 5];
function doStuff(arr) {
   //arr is a variable that contains the first parameter used to invoke the 
   //function, if the variable is an object then it is passed by reference
   //
   //Here you are assigning the variable "arr" the value of a new array
   arr = [];
};

doStuff(myArray);
console.log(myArray)// => [2,3,4,5]

In the second example you are modifying the passed object, everything is still being passed the same way, difference is you are acting on the object that was passed rather than assigning the variable a new value. 在第二个示例中,您正在修改传递的对象,所有内容仍然以相同的方式传递,不同之处在于您正在对传递的对象执行操作,而不是为变量分配新值。

 function changeSecondIndex(arr){
      //Acting on index 2 of the passed array and setting the value to 25
      arr[2] = 25;
 }

 changeSecondIndex(myArray)
 console.log(myArray) // => [2,3,25,5]

If you wanted to do something similar to what you are trying to do in the first example could have some sort of object that contains a state with your variables in it 如果你想做类似你在第一个例子中尝试做的事情,可能会有某种对象包含一个包含变量的状态

var workingVars= {arr: [2, 3, 4, 5]};
function doStuff(env) {
   // here you are assigning a new empty array to arr property of 
   // passed parameter
   env.arr = [];
};
doStuff(workingVars);
console.log(workingVars.arr)// => []

You don't need a function and arguments to experiment this. 您不需要函数和参数来进行实验。 In JS [] and {} are object creation patterns (literal) and breaks the referral. 在JS []{}是对象创建模式(文字)并打破引用。 Let's see... 让我们来看看...

var a = [1,2];
var b = [2,4];
var c = a; // c references a array.
var d = b; // d references b array
a.length = 0; // a becomes []
b = []; // b becomes []
console.log(c); // [] c still references a
console.log(d); // [2,4] d is no more a reference to b

Of course the same applies to the objects; 当然这同样适用于物体;

var o1 = {x:1, y:2};
var o2 = {x:2, y:4};
var p1 = o1; // p1 references o1
var p2 = o2; // p2 references o2
delete o1.x;
delete o1.y;
console.log(o1); // Object {}
console.log(p1); // Object {} p1 still references o1
o2 = {};
console.log(o2); // Object {}
console.log(p2); // Object {x: 2, y: 4} p2 is no more a reference to o2

To understand why this is happening you must first remember that an Array in Javascript is an object . 要理解为什么会发生这种情况,您必须首先记住Javascript中的数组是一个对象 The reason your arr = [] is taking no affect on your global declaration is for the following : 您的arr = []对您的全局声明没有任何影响的原因如下:

Reason 1 : 原因1:

arr = [] does not clear an array , it just creates a new array object in memory no matter what . arr = []不清除数组,它只是在内存中创建一个新的数组对象 ,无论如何。

So in your function : 所以在你的功能中:

function doStuff(arr) {
   arr = [];
};

doStuff(myArray)

you are just taking in myArray and making a new empty version of it in a local scope which leads to reason 2 . 你只是接受myArray并在本地范围内创建一个新的空版本,这导致了原因2。

Reason 2 : 原因2:

Any new object / variable declared in a function is confined to the local scope of that function 函数中声明的任何新对象/变量都局限于该函数的局部范围

so : 所以:

function doStuff(arr) {
   arr = [];
};


doStuff(myArray) //logs [1,2,3,4]

arr = [] was destroyed at the closing bracket of doStuff function an cannot exist on the outside . arr = [] doStuff函数的结束括号中被销毁,外部不存在。

Reason 3 : 原因3:

function doStuff(arr){

 arr[2] = 25;

}

doStuff(myArray)

This works because you're accessing myArray in arr variable and modifying a property off myArray object, this is perfectly normal in javascript. 这是有效的,因为你在arr变量中访问myArray并修改myArray对象的属性,这在javascript中是完全正常的。

In short : = operator assigns , re-assign s , and create s ... 简而言之: =运算符分配重新分配 s,并创建 s ...

arr = [] is an assignment to new myArray object within your function and is also trapped in the scope of your function . arr = []是函数中新myArray对象赋值,也被困在函数范围内。

arr[2] = 25 accesses myArray object temporarily and re-assigns a property . arr[2] = 25临时访问myArray对象并重新分配属性

Hope this helps.. 希望这可以帮助..

You have defined global var myArray. 您已定义全局var myArray。 And then you want to access this global array and change it in function. 然后你想要访问这个全局数组并在功能上进行更改。 Yes it will overwrite global array, but only when you specific function. 是的,它将覆盖全局数组,但仅限于您具体的功能。 in your case function doStuff(). 在你的情况下函数doStuff()。

If you don't call doStuff(), it will keep global inicialization values! 如果你不调用doStuff(),它将保持全局的inicialization值!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM