Javascript的循环中的k-v、v-k

原创
2015/09/10 11:40
阅读数 990

jQuery中有一个 map方法,循环时候是 k-v:

$(':checkbox[checked]').map( (k, v) => $(v).val() ).get();

到了js这里的map,就变成了 v - k

['a', 'b', 'c'].map( (v, k) => v) ;

js这样设计其实是为了方便省略 k,因为很多时候只需要v就够了,比如:

['2', '3', '4'].map( v => parseInt(v) );

但过度的省略可能会带来歧义,比如 :

['2', '3', '4'].map(parseInt);

=> [2, NaN, NaN]

这是一个非常著名的js大坑。

原因是 parseInt 的原型其实是 parseInt(string, base), 第二个参数其实是转换的进制,等价成了这样:

['2', '3', '4'].map( (v, k) => parseInt(v, k) );

循环调用分别为:parseInt('2', 0);  parseInt('3', 1);  parseInt('4', 2);

所以最好写成:

['2', '3', '4'].map( v => parseInt(v) ) ;

因为经常会忘记第一个到底是k,还是v,最好写成这样:

['2', '3', '4'].map( (v, k) => parseInt(v) ) ;

鉴于jQuery和原生js的map函数都是非常常用的,k,v 还是 v,k,经常容易混淆,这样的不一样设计非常不好。

再看看其他语言的 GO的,go没有map,但range也差不多,go使用的是 k, v:

for k, v := range []byte{'a', 'b', 'c'} {
    fmt.Printf("%d %c\n", k, v)
}

=> 
0 a
1 b
2 c

考虑到go不允许出现未使用的参数,所以很多时候需要这样:

for _, v := range []byte{'a', 'b', 'c'} {
    fmt.Printf("%c\n", v)
}

虽然是麻烦了,但依然遵循 k, v 这样熟悉的排列方式。

Ruby中的循环,可选带上Index,但是确是js这样的 v - k 方式:

2.2.2 :005 > ('a'..'c').each_with_index{|v, k| puts "#{v} #{k}" }
a 0
b 1
c 2

ruby好记住,主要是因为each_with_index 和 each,既然是带了index,那index在后面就刚刚好。

到底应该k-v还是,v-k,不能统一一下嘛。一会儿k-v,一会儿v-k,真是够了。

展开阅读全文
加载中
点击加入讨论🔥(1) 发布并加入讨论🔥
打赏
1 评论
1 收藏
0
分享
返回顶部
顶部