javascript中的内存问题

Jam*_*air 1 javascript memory memory-management instance

每次实例化一个对象或一个函数时,它是存储内存还是只是存储了原始值的变量.

例如 - var myArray = new Array();var num = function(){};

T.J*_*der 6

当你这样做

var myArray = new Array();
Run Code Online (Sandbox Code Playgroud)

您在内存中创建一个对象,并在该变量中存储对该对象的引用myArray.(引用就像是C/C++中的指针.它是一个告诉JavaScript引擎对象所在的值.)例如:

+?????????+           
| myArray |           
+?????????+           +????????????????????????????+
|   ref   |??????????>| instance of an array       |
+?????????+           +????????????????????????????+
                      | length = 0                 |
                      +????????????????????????????+

当你这样做时:

var n = 2;
Run Code Online (Sandbox Code Playgroud)

您将实际值2存储在n:

+?????????+
|    n    |
+?????????+
|    2    |
+?????????+

这是原始类型和对象类型之间的本质区别.(字符串有点模糊,但你可以假装JavaScript中的原始字符串就像数字一样,引擎会隐藏一些细节.)

这是一个重要的区别,因为JavaScript是纯粹的值传递语言,因此当您调用函数并将参数传递给它时,将传递而不是变量.考虑:

function foo(index, a) {
    return a[index];
}
Run Code Online (Sandbox Code Playgroud)

foo函数接受索引和数组,并返回该索引处数组中元素的值.

x = foo(n, myArray);
Run Code Online (Sandbox Code Playgroud)

调用foo函数并传递在n(2)和所述myArray(一个数组的引用).因此index接收相同的值n有(2),并且a接收相同的值myArray具有(对数组的引用).因为在的情况下的值a,并myArray是一个数组的引用,它们都指代相同的数组:

+?????????+
| myArray |
+?????????+
|   ref   |???????+    
+?????????+       |    
                  |    +????????????????????????????+
+?????????+       +???>| instance of an array       |
|    a    |       |    +????????????????????????????+
+?????????+       |    | length = 0                 |
|   ref   |???????+    +????????????????????????????+
+?????????+

+?????????+
|    n    |
+?????????+
|    2    |
+?????????+

+?????????+
|  index  |
+?????????+
|    2    |
+?????????+

赋值语句也是如此,原因相同:左侧的变量=接收右侧表达式的.

var n2 = n;
var a2 = myArray;
Run Code Online (Sandbox Code Playgroud)

n2接收n(2)a2的值,并接收myArray(对数组的引用)的值.如果我们图解myArray,a2,n,和n2,该图将是等同于上面的一个foo的参数indexa.

由于myArraya指向同一个数组(引用同一个对象),如果它们对数组执行mutator操作,则结果可通过任一引用显示.例如,向数组添加一个新元素是一个mutator操作,它会更改对象:

alert(myArray.length); // 0
alert(a.length);       // 0
a.push("test");
alert(myArray.length); // 1
alert(a.length);       // 1
Run Code Online (Sandbox Code Playgroud)

理解那里发生的事情很重要.该变量 myArraya没有改变,但对象,他们指了.相反:

a = someOtherArray;
Run Code Online (Sandbox Code Playgroud)

现在a完全指向其他地方,它的不再与值相同myArray,因此它不是指同一个对象.


偏离主题:更好的写作方式

var myArray = new Array();
Run Code Online (Sandbox Code Playgroud)

var myArray = [];
Run Code Online (Sandbox Code Playgroud)

最终结果是相同的(创建并分配了一个新数组myArray),但第二个结果更短,效率更高,并且保证您将得到一个数组(而第一个可以在不寻常的情况下,不给出你是一个阵列 - 如果有人遮住了这个Array符号).

同样,你可以写

var obj = new Object();
Run Code Online (Sandbox Code Playgroud)

像这样

var obj = {};
Run Code Online (Sandbox Code Playgroud)

......由于同样的原因,它们也有类似的好处.