- 主题:请高手帮我看一段关于javascript的二维数组的程序,有点见鬼了
byRef vs byVal
【 在 cowell (紫禁飞狐) 的大作中提到: 】
: st1和st2是两个二维数组(实际上是操作从Excel来的数据),从文本取得text后通过两次split得到。a和b代表st1的第a列和st2的第b列(都从0起算)。另建两个数组st1a和st2a,分别用来存取st1中a列与st2中b列相同元素对应的行,以及类似的st1b和st2b,分别用来存放剩余部分。
: 关键部分代码如下(有几个alert是调试用的,不用理会):
: ===========
: ...................
--
FROM 218.197.83.*
var st1a=new Array();
var st1b=new Array();
var st2a=new Array();
var st2b=new Array();
var sta=new Array();
st1b=st1;
st2b=st2;
中,st1b=st1则两者代表同一个对象;st1b=new Array()中的newArray()被掉丢了。
如果你要复制数组,不要st1b=st1,而是先new Array(),然后用循环拷贝:
var st1b=[];
for(...){
//copy each element
}
其它没仔细看。
【 在 cowell (紫禁飞狐) 的大作中提到: 】
: 不好意思,没看懂。能再稍微详细点么?
: 非常感谢!
--
FROM 218.197.83.*
从可读性上看,循环要好啊。
【 在 cowell (紫禁飞狐) 的大作中提到: 】
: nimi,看漏你的了。
: 我也刚才在网上查了一下,原来可以用slice高效克隆数组,过来继续回复,才看到你已经把答案写那里了。:)
: var clone = myArray.slice(0);// naive clone
: ...................
--
FROM 218.197.83.*
好吧。我只能说你牛得太快了。
【 在 cowell (紫禁飞狐) 的大作中提到: 】
: 循环要好几行,看起来也费尽。还不如直接.slice(0)然后放一条注释在后面说明是复制数组来的可读性好。:)
--
FROM 218.197.83.*
前者这个主要是js自身的设计问题——块没有局部变量;下一版本可能用let解决。(我觉得设计上var 两次应该报错才对---edit:发现下一版本js就不允许let两次同一变量)。
后者是closure的问题,跟js关系不大吧——换个语言还不是如此?除非不用closure
【 在 nimi (泥股拉不二八雞) 的大作中提到: 】
: 由于js奇葩的scoping rule,扭曲的by-ref closure,javascript里的循环是坑人的,能不用就不用,很容易被坑。
: 可以看看coffeescript里的循环编译成什么样的javascript,比较复杂,这都是为了保证程序的正确性。
: 比如这个:
: ...................
--
修改:ottffsse FROM 218.197.83.*
FROM 218.197.83.*
closure设计的本意就是capture住所返回函数的外部变量吧。这样的话,byVal和byRef是程序员的责任啊。
像你前面所提到的问题,完全可以每次循环时新建一个变量解决。
如果都是byVal, 那么1)若closure就是想记住上次的值怎么办?2)如果是大对象复制很耗内存怎么办?
【 在 nimi (泥股拉不二八雞) 的大作中提到: 】
: closure是从函数式编程(确切的说是从scheme)里面来的,那里面一般都不会使用变量,甚至根本就不能用变量。像ML里面,就算用了变量,closure的capture也是by value而不是by ref的,所以不会出这样的问题
: C++11里面的closure如果直接写也是by value,加上了&才是by ref
: 所以说,这个问题虽然其它语言也有,但是javascript是最严重的
--
修改:ottffsse FROM 218.197.83.*
FROM 218.197.83.*