今晚跑去华工参加百度Web前端的笔试,做完之后交卷,本来感觉是“为之四顾,为之踌躇满志”的。
其中一道题目是关于数组的,回来在电脑上面一敲,顿时为自己的智商和知识羞愧了。
多话不说,直接上题目吧。大概是酱紫的:
代码如下,请写出输出的结果。
1 <script>
2 var str = 'john';
3 var str2 = 'angus';
4
5 var arr1 = str.split('');
6 var arr2 = arr1.reverse();
7 var arr = str2.split('');
8 var arr3 = arr2.push(arr);
9
10 console.log(arr1.length, arr1.slice(-1));
11 console.log(arr3.length, arr3.slice(-1));
12 </script>
简单说说体现博主低智商的地方,便是将第8行的push当做了直接在arr2的后面逐个加上arr的元素。唉,不得不说,这是多么脑残,多么天真。
行了,废话不说,先说在FF下测试的答案:
第10行打印的是:5 Array [ Array[5] ];
第11行则没有打印结果。(这让我很费劲。。。稍后再说。。)
你,猜到了吗?
博主没有猜到两点:
1、第10行显示arr1的length是“5”;(BUT,如果我没有犯上面说过的理解错push()的脑残错误,这道题我也不会猜对结果);
2、第11行居然没有任何输出,博主试了N++次都不敢相信。
最后,努力百度(唉,还是逃不出度娘的手掌心),终于解决了上述两个问题(作为一个刚刚入门的人,有不是问题的地方嘛)。。。
第一个问题,见http://www.cnblogs.com/0banana0/archive/2011/11/17/2252639.html:
“ 结论:js数组是引用类型,它只允许通过索引来获取或改变数组的值 引用类型的东西都是不能通过(它赋值过的外部变量)所改变的 也就是(它赋值过的外部变量)这个值改变了原数组不会有任何变化。”
所以虽然我们是在arr3上应用push()方法,但最终影响的还是arr1、arr2、arr3共同指向的数组。
上述博文一楼评论说得很明白:
JS中没有指针,只有传值(value)与传址(reference引用)的区
var a = [1,2,3,4] //a不仅是数组,还是个对象,实际上a就是对[1,2,3,4]的引用
var b=a
var c=a
//以上两条赋值语句建立了b与c 对a即[1,2,3,4]的引用,无论改变a 还是b抑或c 都是对[1,2,3,4]的操作,这就是传址(堆中操作)
var d=a[1] //则是把a[1]的值"1"传递给d,对d的改变则不会影响a[1],即所谓的传值(栈中操作)
第二个问题是第11行代码无输出的问题,最后我在新浪博客上面得到了答案(http://blog.sina.com.cn/s/blog_51c99bb20101o48m.html):
unshift() 方法可向数组的开头添加一个或更多元素,并返回新的长度。1 <script> 2 var str = 'john'; 3 var str2 = 'angus'; 4 var a = str.split(''); 5 var b = str2.split(''); 6 var c = a.splice(2,1,"test"); 7 8 console.log(a);//Array [ "j", "o", "test", "n" ] 9 console.log(b);//Array [ "a", "n", "g", "u", "s" ] 10 console.log(c);//Array [ "h" ] 11 </script>
1 <script> 2 var str = 'john'; 3 var a = str.split(''); 4 var c = a.sort(); 5 6 console.log(c);//Array [ "h", "j", "n", "o" ] 7 console.log(a);//Array [ "h", "j", "n", "o" ] 8 </script>
而concat()、slice()操作则对数组都不影响。。。。(说到concat()方法,想到了昨天看到的高效复制数组的方法:var newArr = arr.slice(0)和var newArr = arr.concat(),记下来备用吧。。。嗯,还有网址:http://www.jb51.net/article/5769.htm)