isArrayLike

Testing for array-like-ness.

by kflorence

HTML

<div id="element">
    <div id="child1"></div>
    <div id="child2"></div>
</div>

<form id="form">
    <input type="text" name="text1" />
    <input type="text" name="text2" />
</form>

<h1><span class="pass">pass</span> / <span class="fail">fail</span></h1>
<ul id="log"></ul>

CSS

form, iframe, #element { display: none; }
.pass { background: #53DB53; }
.fail { background: #DE6A6A; }

JavaScript

(function( jQuery ) {
    var aps = Array.prototype.slice,
        hasOwn = Object.prototype.hasOwnProperty;
        // Determines if we can treat an object like an array.
        isArrayLike = function( obj ) {
            var length;

            return obj && ( obj instanceof jQuery || ( typeof obj === "object" && !jQuery.isWindow( obj )
                && ( ( 0 in obj ) && aps.call( obj, 0, 1 )[ 0 ] === obj[ 0 ] ) ) || jQuery.isArray( obj ) );
        };

    function ok( bool, msg ) {
        $("<li>").text( msg ).addClass( bool ? "pass" : "fail" ).appendTo( "#log" );
    }
    
    var k, f = function() {};
    f.foo = "bar";
    
    var valid = {
        "[]": [],
        "[ undefined, null ]": [
            undefined,
            null
        ],
        "jQuery": jQuery(),
        "nodeList": document.getElementsByTagName("div"),
        "Node.childNodes": jQuery("#element")[0].childNodes,
        "HTMLCollection": jQuery("form")[0].elements,
        "function arguments": (function() { return arguments; })()
    }, invalid = {
        "null": null,
        "undefined": undefined,
        "empty string": "",
        "string": "foo",
        "0": 0,
        "1": 1,
        "number": 242,
        "function": f,
        "{}": {},
        "window": window,
        "document": document,
        "{ Array-like }": {
            length: 2,
            0: "First Item",
            1: "Second Item"
        },
        "{ array-like } length is string": {
            length: "2",
            0: "zero",
            1: "one"
        },
        "{ array-like } no properties": {
            length: 2
        },
        "{ Array-like } with undefined and null": {
            length: 3,
            0: undefined,
            1: null,
            2: "foo"
        },
        "Node": document.body,
        "RegExp": /foo|bar/,
        "Date": new Date()
    };
    
    for ( k in valid ) {
        ok( isArrayLike( valid[ k ] ), "Valid: " + k );
    }
    
    for ( k in...