JavaScript 的 Array 无法清空的奇怪问题
高洛峰
高洛峰 2017-04-10 15:04:09
[JavaScript讨论组]
clear = function (ary) {
  ary = [];
};

a = [1, 2, 3];

clear(a);

console.log(a);

在调用 clear(a) 的时候,不是已经把进行了赋值 a = []
为什么 console.log(a) 还是输出 [1, 2, 3]

高洛峰
高洛峰

拥有18年软件开发和IT教学经验。曾任多家上市公司技术总监、架构师、项目经理、高级软件工程师等职务。 网络人气名人讲师,...

全部回复(11)
迷茫

清空函数体用ary.length = 0,手机不方便,过会给你解释原因。

原因来了:
传参时, ary[1, 2, 3]的引用(类似于指针);
改变ary的内容会反映到外面, 如arr.push(4);
但是直接覆盖ary[]则相当于ary指向新的对象, 不再指向原来的[1, 2, 3], 但是[1, 2, 3]还在那, 即你没有对其做任何改动.

PHP中文网

额...

1. clear = function (ary) {
ary = [];
};

你要明白,传参数传的是数值,不是参数名!这里传的是参数值[1,2,3],不是参数名 a ,会把[1,2,3]赋值给ary,所以此时 ary = [1,2,3] ,然后给ary赋值为空数组,ary = []。a 还是原来的值,并没有改变

2.console.log(a); 这里的 a 依然还是全局变量中的 a

可以F12 运行下下面的代码:

var clear = function (ary) {
    console.log(ary); //输出:[1,2,3]     
    ary = [];
    console.log(ary); //输出:[]  
    console.log(a); //输出:[1,2,3]  
};
var a = [1, 2, 3];
clear(a);
console.log(a); //输出:[1,2,3]  

解释为什么修改成 ary.length = 0;后数组a 也会变成空数组,而 ary = [ ]不会有影响。

上面也通俗的讲了传参的是数值,准确地讲是JS中所有的函数都是按值传递的,不论这个参数是基本类型的还是引用类型的。
基本类型的参数比较好理解,相当于函数的局部变量,在函数体内修改参数不会影响函数外部的变量。
如果是引用类型,此题就是,这个数组对象 a 被传递到clear函数中之后复制给了ary,在这个函数的内部,arya 引用的都是同一个对象,所以在函数内部改变这个引用对象的属性的时候,函数外部的a也会相应的改变。
好,现在要捋一捋ary.length = 0;ary = [ ] 这两种清空数组的方式的区别了,简单来说,前者保留了数组对象的其他属性,而后者没有,因为其实它并不能说是严格意义的清空数组,只是将ary重新赋值为空数组,与 a 没有半毛钱关系了,所以如果之前的数组没有引用在指向它,将等待垃圾回收。
所以,如果是ary = [ ],此时arya引用了不同的对象,则对 数组 a 没有影响,如果是ary.length = 0;因为arya依然引用同一对象,所以修改了ary后也会反应到a上。

不知道有没解释清楚。

黄舟

一旦用了=给ary赋值,这就是一个新的数组了(对象也是同理)
要清空数组,
你可以通过改变数组的length属性,如ary.length = 0,
或则使用操纵当前数组的方法,如ary.splice(0,ary.length)
总之不要产生新的数组,

ringa_lee

ary.length = 0

阿神

其实就是JS对象的基本知识,传值传的是对象的引用,而JS中数组也是一个对象。
所以,ary.length = 0 修改的是[1,2,3]这个数组的长度,因此能起到作用;
ary = [] 则是将[]的引用赋值给ary ,ary因此指向了[],现在你还能指望ary修改[1,2,3]?
所以a引用的[1,2,3]并没有变化

阿神

进入函数:
ary=a;//参数值传递
这个时候:
因为a->[1,2,3];//->表示指向
所以ary->[1,2,3];
ary=[];//函数体执行
这个时候:
ary->[];
但是a->[1,2,3];//a没有改变;

阿神

太多太大段的描述,看的好累。我来精简一下:

数字,字符串等都是值类型,而 plain object,array 等都是引用类型。

给你举个栗子你立马能明白:

jsvar a = [1,2,3];
var b = a;

b.push(4);
console.log(a); // [1,2,3,4]

var num = 123;
var _num = num;
_num = 456;

console.log(num); // 123

虽不是就题论题,但思路很重要。

PHPz

function clear(arry){
arry.length = 0;
return arry;

PHP中文网

arry.length = 0 修改的还是原来数组
arry =[] []的引用赋值给arry,而arry原来指向的数组并没有改变

伊谢尔伦

aarr都只是保存了一个地址,这个地址指向堆中的数据[1, 2, 3],调用clear时,只是把a的地址拷贝给arr,在clear函数里面,arr = []指向了另外一个地址,但并不影响外面的a,类似的情况,请参考nodejs中module.exportsexports的区别!

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号