JavaScript Array迭代返回的值多于值

jer*_*iuh 2 javascript arrays prototype scriptaculous

这很简单我很困惑.我有以下内容:

var x = 'shrimp';    
var stypes = new Array('shrimp', 'crabs', 'oysters', 'fin_fish', 'crawfish', 'alligator');
for (t in stypes) {
    if (stypes[t] != x) {
        alert(stypes[t]);
    }
}
Run Code Online (Sandbox Code Playgroud)

一旦值迭代,它就开始返回十几个函数

function (iterator, context) {
    var index = 0;
    iterator = iterator.bind(context);
    try {
        this._each(function (value) {iterator(value, index++);});
    } catch (e) {
        if (e != $break) {
            throw e;
        }
    }
    return this;
}
Run Code Online (Sandbox Code Playgroud)

到底他妈发生了什么?

编辑:在这些脚本中我使用的是http://script.aculo.us/prototype.jshttp://script.aculo.us/scriptaculous.js 我记得现在读到原型扩展数组的方式,我打赌这个是它的一部分.我该如何处理?

Qui*_*son 7

for枚举是要去了每一个你传入对象的成员.在这种情况下,一个数组恰好具有作为成员的函数以及传递的元素.

你可以重写你的for循环以检查是否typeof stypes[t] == "function"或yada yada.但IMO你最好只修改循环到元素..

for(var i = 0, t; t = stypes[i]; ++i){
    if (t != x) {
        alert(t);
    }
}
Run Code Online (Sandbox Code Playgroud)

要么

for(var i = 0; i < stypes.length; ++i){
    if (stypes[i] != x) {
        alert(stypes[i]);
    }
}
Run Code Online (Sandbox Code Playgroud)

我想将我的最后一条评论迁移到答案,为第一种类型的循环添加警告的通知.

来自Simon Willison的"重新介绍JavaScript" ..

for (var i = 0, item; item = a[i]; i++) {
    // Do something with item
}
Run Code Online (Sandbox Code Playgroud)

这里我们设置两个变量.for循环中间部分的赋值也进行了真实性测试 - 如果成功,则循环继续.由于每次都会增加i,因此数组中的项目将按顺序分配给项目.找到"假"项(例如未定义)时,循环停止.

请注意,此技巧仅应用于您知道不包含"falsy"值的数组(例如,对象数组或DOM节点).如果您正在迭代可能包含0的数字数据或可能包含空字符串的字符串数据,则应使用i,j惯用法.