2

这太简单了,我很困惑。我有以下内容:

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]);
    }
}

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

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;
}

到底他妈发生了什么?

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

4

4 回答 4

7

for枚举将遍历您传递给它的对象的每个成员。在这种情况下是一个数组,它恰好具有作为成员的函数以及传递的元素。

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

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

或者

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

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

来自Simon Willison 的“A re-introduction to JavaScript” ..

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

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

请注意,此技巧只应用于您知道不包含“虚假”值的数组(例如对象数组或 DOM 节点)。如果您正在迭代可能包含 0 的数字数据或可能包含空字符串的字符串数据,您应该使用 i, j 习惯用法。

于 2009-09-29T23:17:12.817 回答
3

你想做:

for (var i in object) {
    if (!object.hasOwnProperty(i))
        continue;
    ... do stuff ...
}

至于..in 枚举迭代对象及其原型链上存在的所有属性(可枚举或其他)。该hasOwnProperty检查将迭代限制为您要枚举的实际对象上的那些属性。

ES5 让库开发人员的事情变得更好(并帮助避免这些事情),但我们不会在很长一段时间内看到发布浏览器:-(

[编辑:用继续替换返回。拉拉拉拉拉拉拉拉拉拉拉拉拉拉拉拉拉拉拉拉拉拉拉拉拉拉拉拉拉拉拉;)]

于 2009-09-29T23:29:06.090 回答
1

由于原型为了您的方便而扩展了数组,您应该利用它。您的示例可以重写为:

var x = 'shrimp';    
var stypes = new Array('shrimp', 'crabs', 'oysters', 'fin_fish', 'crawfish', 'alligator');
stypes.without(x).each(alert);
于 2011-01-24T12:40:43.383 回答
-3

它应该是

for (t in stypes) {
    if (t != x) {
        alert(t);
    }
}
于 2009-09-29T23:17:43.767 回答