javascript for in

前段时间和朋友提到 javascript,可惜没有 foreach。朋友当时便有点诧异。我补充说 for…in 其实还是有的,只是不可预期而已。
使用 for…in 遍历数组的方法。
var lst = [1, 2, 3, 4, 5, 6];
// 输出 123456
for (var i in lst)
document.write(lst);目前一切都还正常。但试着加上一行代码,就会有变化。
var lst = [1, 2, 3, 4, 5, 6];
Array.prototype.xxx = 'XXX'; // +++
// 输出 123456XXX
for (var i in lst)
document.write(lst);看上去给 array 加上一个 xxx 明显是一件极其 silly 的事情。但是想一下很久之前 IE 中的 array 是没有 push 方法的,那时我们经常会用这种方法给 IE 加上 push。
这样看来顺理成章,for…in 不能用了。
如果再考虑到低版本的 IE 不支持 push,早期 “安全” 的 javascript 就会像这个样子。
var lst = [1, 2, 3];

lst[lst.legnth] = 4; // push 4
lst[lst.legnth] = 5; // push 5
lst[lst.legnth] = 6; // push 6

for (var i = 0; i++; i < lst.legnth)
document.write(lst);没有经历过那个时代的朋友乍一看到,不禁会问,这,这是什么情况?
—— 这确实是太糟糕了。
异曲同工之妙,string 也是可以 for…in 遍历的。
var str = 'abcdef';
// 输出 abcdef
for (var i in str)
document.write(str);杯具的是,给 string 加 strip 之类的方法也是很常见的。这样才是最 “面向对象” 的扩展方式,不是吗?
var str = 'abcdef';
// var strip = function(s) { return s.replace(/^[\r\n\s\t]*|[\r\n\s\t]*$/g, ''); }; // XXX 不够面向
String.prototype.strip = function() { return this.replace(/^[\r\n\s\t]*|[\r\n\s\t]*$/g, ''); };
for (var i in str)
document.write(str);当然最抱歉的写法应该是 “ Object.prototype.xxx = XXX ” 了。
使用 javascript 小心 IE。这个大家都清楚,自不必多说。如果 javascript 中引用了第三方代码,或会被别人用到,for…in 最好不用。prototype 也尽量少用。
我以前说过,对于成熟的 library / framework 开发者来说,接口过多和接口太少,其实就是一码事。
特性越多,功能越少,“ for…in vs prototype ” 这是一个典型例子。
Tags: 

延伸阅读

最新评论

发表评论