Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
268 views
in Technique[技术] by (71.8m points)

arrays - JavaScript Loops: for...in vs for

I faced a strange behaviour in Javascript. I get

"Object doesn't support this property or method"

exception for the removeAttribute function in the following code:

var buttons = controlDiv.getElementsByTagName("button");
for ( var button in buttons )
    button.removeAttribute('disabled');

When I change the code with the following, the problem disappears:

var buttons = controlDiv.getElementsByTagName("button");
for ( var i = 0; i < buttons.length; i++ )
    buttons[i].removeAttribute('disabled');

What is the value of button inside the for...in?

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Don't use for..in for Array iteration.

It's important to understand that Javascript Array's square bracket syntax ([]) for accessing indicies is actually inherited from the Object...

obj.prop === obj['prop']  // true

The for..in structure does not work like a more traditional for..each/in that would be found in other languages (php, python, etc...).

Javascript's for..in is designed to iterate over the properties of an object. Producing the key of each property. Using this key combined with the Object's bracket syntax, you can easily access the values you are after.

var obj = {
    foo: "bar",
    fizz: "buzz",
    moo: "muck"
};

for ( var prop in obj ) {
    console.log(prop);      // foo / fizz / moo
    console.log(obj[prop]); // bar / buzz / muck
}

And because the Array is simply an Object with sequential numeric property names (indexes) the for..in works in a similar way, producing the numeric indicies just as it produces the property names above.

An important characteristic of the for..in structure is that it continues to search for enumerable properties up the prototype chain. It will also iterate inherited enumerable properties. It is up to you to verify that the current property exists directly on the local object and not the prototype it is attached to with hasOwnProperty()...

for ( var prop in obj ) {
    if ( obj.hasOwnProperty(prop) ) {
        // prop is actually obj's property (not inherited)
    }
}

(More on Prototypal Inheritance)

The problem with using the for..in structure on the Array type is that there is no garauntee as to what order the properties are produced... and generally speaking that is a farily important feature in processing an array.

Another problem is that it usually slower than a standard for implementation.

Bottom Line

Using a for...in to iterate arrays is like using the butt of a screw driver to drive a nail... why wouldn't you just use a hammer (for)?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...