leuisken.github.io/posts_2014-2016/2015-04-29-array-push.html
2016-04-19 16:44:27 +08:00

141 lines
3.6 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: JavaScript中Array.push进去的是指针
labels: ["前端"]
description: 说来惭愧,学前端到今天才发现这么一个问题。不求甚解,早晚会出问题的。
---
<p>说来惭愧,学前端到今天才发现这么一个问题。不求甚解,早晚会出问题的。</p>
<p>起因是,我写了大概如下的代码。</p>
{% highlight javascript %}
var numCol = [],
temp = [1];
for(var i = 0; i &lt; 2; i++){
numCol.push(temp);
console.log(numCol);
temp[0] = 4;
}
{% endhighlight %}
<p>Console.log的结果如下</p>
{% highlight console %}
[ [1] ]
[ [4], [4] ]
{% endhighlight %}
<p>测试环境为Node v0.10.35。在Chrome下测试发现console.log()出来的好像也是指针。</p>
<p>问题就是array.push的是一个指针。接下来请看下面的对比样例</p>
{% highlight javascript %}
var numCol = [],
temp = [1];
for(var i = 0; i &lt; 2; i++){
numCol.push(temp);
console.log(numCol);
temp = [4];
}
{% endhighlight %}
<p>输出结果:</p>
{% highlight console %}
[ [1] ]
[ [1], [4] ]
{% endhighlight %}
<p>我们想要的结果出来了。之后就在想这个问题,如果换成对象的话,会怎么样呢?测试代码如下:</p>
{% highlight javascript %}
var numCol = [],
temp = {
"a": 'a'
};
for(var i = 0; i &lt; 2; i++){
numCol.push(temp);
console.log(numCol);
temp.a = 'b';
}
{% endhighlight %}
<p>输出:</p>
{% highlight console %}
[ { a: 'a' } ]
[ { a: 'b' }, { a: 'b' } ]
{% endhighlight %}
<p>基本可以确定是指针的问题了,接下来用字符串测试,代码如下:</p>
{% highlight javascript %}
var numCol = [],
temp = 'abc';
for(var i = 0; i &lt; 2; i++){
numCol.push(temp);
console.log(numCol);
temp[0] = 'b';
}
{% endhighlight %}
<p>输出:</p>
{% highlight console %}
['abc']
['abc', 'abc']
{% endhighlight %}
<p>并没有影响应该说temp[0] = 'b'这句话形同虚设。</p>
<p>之后对字符串进行测试发现temp[0]只有get功能没有set功能。大家可以通过下面的例子理解。</p>
{% highlight console %}
&gt; var a = 'abc'
undefined
&gt; a[0]
'a'
&gt; a[0] = 'b'
'b'
&gt; a[0]
'a'
{% endhighlight %}
<p>这样试下来,我上面说得意思是不是比较明确了?</p>
<p>那么如何去解决这个问题呢?先想的是两个数组不停相互赋值,看看可不可以?别急,在试验前先分析一下,看看我下面的测试:</p>
{% highlight console %}
&gt; var a = [1, 2, 3]
undefined
&gt; var b = a
undefined
&gt; a[0] = 4
4
&gt; b
[ 4, 2, 3 ]
{% endhighlight %}
<p>握了棵草。。。赋值传的也是指针啊我突然见感受到了弱类型语音深深的恶意。但如果站在这个角度去看这个问题的话其实这就是所谓的浅复制和深复制的问题。其实所谓浅复制就是像这样b = a实际上是让b也指向aa变b也变b变a也变而深复制就是让b具有a的内容a变b不变b变a不变。</p>
<p>之后就去查js里面解决深浅复制问题的方案了。对于数组有两个现成的函数都可以处理对象的话就要自己写代码遍历了。数组的解决方案也很简单直接贴上解决后的代码。</p>
<p>方案一slice()</p>
{% highlight javascript %}
var numCol = [],
temp = [1];
for(var i = 0; i &lt; 2; i++){
numCol.push(temp.slice(0));
console.log(numCol);
temp[0] = 4;
}
{% endhighlight %}
<p>方案二concat()</p>
{% highlight javascript %}
var numCol = [],
temp = [1];
for(var i = 0; i &lt; 2; i++){
numCol.push(temp.slice(0));
console.log(numCol);
temp[0] = 4;
}
{% endhighlight %}
<p>现在问题就解决了!</p>