clear = function (ary) {
ary = [];
};
a = [1, 2, 3];
clear(a);
console.log(a);
在调用 clear(a)
的时候,不是已经把进行了赋值 a = []
?
为什么 console.log(a)
还是输出 [1, 2, 3]
?
clear = function (ary) {
ary = [];
};
a = [1, 2, 3];
clear(a);
console.log(a);
在调用 clear(a)
的时候,不是已经把进行了赋值 a = []
?
为什么 console.log(a)
还是输出 [1, 2, 3]
?
额...
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
,在这个函数的内部,ary
和a
引用的都是同一个对象,所以在函数内部改变这个引用对象的属性的时候,函数外部的a也会相应的改变。
好,现在要捋一捋ary.length = 0;
和 ary = [ ]
这两种清空数组的方式的区别了,简单来说,前者保留了数组对象的其他属性,而后者没有,因为其实它并不能说是严格意义的清空数组,只是将ary
重新赋值为空数组,与 a
没有半毛钱关系了,所以如果之前的数组没有引用在指向它,将等待垃圾回收。
所以,如果是ary = [ ]
,此时ary
和a
引用了不同的对象,则对 数组 a 没有影响,如果是ary.length = 0;
因为ary
和a
依然引用同一对象,所以修改了ary
后也会反应到a
上。
不知道有没解释清楚。
传入 ary 的并不是 全局数组 a 的值哦!如果学过 c 的话就是类似于 c 的指针,如果没学过就当我没说 XD
将你的全局数组传入到 局部变量 ary 后,就可以通过 ary 修改 那个数组 a 的属性
a.length 啦、a.push() 啦等等等等...
但是你如果直接 ary = [],你就断开了 ary 与你的数组 a 的连接,此时的 ary 变成了新的数组。
一句话 ary.length = 0 可以清空的原因是修改了属性,直接 ary = [] 是断开了连接
我想到了个比较清晰的说法,如下
邻居家有一美女,你看到好喜欢哦(此时美女是邻居家的)
你追上了邻居家的美女,她是你的女朋友了(她依旧是邻居家的,不过此时也是你家的)
女友有个衣服的数组(她身上穿了很多衣服)
你给美女买了衣服(修改了女朋友的属性 nvYou.yiFu.push('名牌内衣'))
晚上要做羞羞的事情了(nvYou.yiFu.length = 0)脱衣服你懂得
所以数组可以被清空
但是!!!有一天,你移情别恋了直接换了女友
你.女友 = 新女友(就是 ary = [])
那么请问你脱新女友的衣服,原来女友的衣服会被脱掉吗?
就酱 XD,还不懂你就是猪猪侠!!!
// 再次补充,你的代码应该翻译成这样
var 人 = 邻居的女儿;
var 邻居女儿的衣服 = [];
// 你给邻居女儿买衣服
邻居女儿的衣服.push('外套', '裤子', '鞋子');
// 重点来了! 你没有清空数组哦,你是换了女友
function 换女友(我的女友) {
我的女友 = [新女友];
}
// 清空数组应该这样写
function 脱衣服(我的女友) {
我的女友.衣服的数量 = 0;
}
// 想用 ary = [] 这样的写法,直接操作数组就可以,详细的如下
你并没有修改到那个数组,而是将函数中的局部变量 ary 重新赋值为一个新的数组 []
正常的代码应该是更有逻辑性的。下面只是个小例子,只是让你了解下是怎么回事
// 我的数组在某个对象中
var oData = {
aArray1: [],
aArray2: []
};
// 赋值
oData.aArray1.push(1);
console.log(oData.aArray1);
clear(oData);
console.log(oData.aArray1);
function clear(oData) {
oData.aArray1 = []; // 此时修改的才是那个数组
}
在你的代码中数组和那个清空函数是有关联的,一般是写在一起比较好。建议看下这个回答
http://segmentfault.com/q/1010000001818410/a-1020000001920291
// 这个类似于其他语言中的类
var MyApp= function() {
function MyApp() {
this.aData = [];
// ... 其他的属性
}
MyApp.prototype.clear = function() {
this.aData = [];
}
return MyApp;
}();
// 接下来是使用了
var oApp = new MyApp();
oApp.aData.push(1);
console.log(oApp.aData);
oApp.clear();
console.log(oApp.aData);
// ------ 输出 ------
[1]
[]
涉及到求职策略的问题,参见 http://www.cnblogs.com/TomXu/archive/2012/02/08/2341439.html 大叔的整个系列都是极好的 http://www.cnblogs.com/TomXu/archive/2011/12/15/2288411.html 力荐!
********分割线*********
额,竟然被踩了,难道不应该“授人以鱼不如授人以渔”!
一旦用了=
给ary赋值,这就是一个新的数组了(对象也是同理)
要清空数组,
你可以通过改变数组的length属性,如ary.length = 0
,
或则使用操纵当前数组的方法,如ary.splice(0,ary.length)
总之不要产生新的数组,
其实就是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 等都是引用类型。
给你举个栗子你立马能明白:
js
var 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
虽不是就题论题,但思路很重要。
a
、arr
都只是保存了一个地址,这个地址指向堆中的数据[1, 2, 3]
,调用clear时,只是把a
的地址拷贝给arr
,在clear函数里面,arr = []
指向了另外一个地址,但并不影响外面的a
,类似的情况,请参考nodejs中module.exports
与exports
的区别!
8 回答4.8k 阅读✓ 已解决
6 回答3.5k 阅读✓ 已解决
5 回答2.9k 阅读✓ 已解决
5 回答6.4k 阅读✓ 已解决
4 回答2.3k 阅读✓ 已解决
4 回答2.8k 阅读✓ 已解决
3 回答2.5k 阅读✓ 已解决
清空函数体用
ary.length = 0
,手机不方便,过会给你解释原因。原因来了:
传参时,
ary
是[1, 2, 3]
的引用(类似于指针);改变
ary
的内容会反映到外面, 如arr.push(4)
;但是直接覆盖
ary
为[]
则相当于ary
指向新的对象, 不再指向原来的[1, 2, 3]
, 但是[1, 2, 3]
还在那, 即你没有对其做任何改动.