http://www.nfriedly.com/techblog/2009/06/advanced-javascript-objects-arrays-and-array-like-objects/

How to Convert Array-Like to Array

If you wish to convert an array-like object to an array for use with array methods, you can use one of the following approaches: use the array slice method in conjuction with call, or use the ECMAScript 6 Array.from method.[4] We will use the following list of links to demonstrate:

<div class="side_links">
<ul>
<li><a href="#byId">getElementById</a></li>
<li><a href="#byTag">getElementsByTagName</a></li>
<li><a href="#byClass">getElementsByClassName</a></li>
<li><a href="#sel">querySelectorAll</a></li>
</ul>
</div>

First we will demonstrate the slice/call approach. We start by using document.querySelectorAll to get a node list containing the links. Then we use call to apply the array slice method to the node list. We assign the result to a variable, and since this variable is an array, we can invoke array methods on it directly, as we demonstrate here with forEach:

// get node list of links
var list = document.querySelectorAll('.side_links li a'); // convert to array using slice and call
var ar = Array.prototype.slice.call( list ); // then can use array methods
ar.forEach( function(v) {
v.onclick = function(e) {
console.log( e.target.innerHTML );
return false;
}
} );

Next we demonstrate the Array.from method of conversion. We pass the result of querySelectorAll to Array.from and assign the result to a variable. We can then use array methods on the resulting array, as we demonstrate here with the ECMAScript 5 every method:

// pass result of querySelectorAll to Array.from
var ar = Array.from( document.querySelectorAll('.side_links li a') );
// display result of applying every method to ar
console.log( ar.every( function(v) { return v.hash } ) ); // true

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Javascript objects and arrays are both incredibly useful. They're also incredibly easy to confuse with each other. Mix in a few objects that look like arrays and you’ve got a recipe for confusion!

We're going to see what the differences between objects and arrays are, how to work with some of the common array-like objects, and how to get the most performance out of each.

What Objects Are

A javascript object is a basic data structure:

var basicObj = {}; // an empty object - {} is a shortcut for "new Object()"

basicObj.suprise= "cake!";

basicObj['suprise']; // returns "cake!"

Using {} instead of new Object(); is know as “Object Literal” syntax.

var fancyObj = {
favoriteFood: "pizza",
add: function(a, b){
return a + b;
}
}; fancyObj.add(2,3); // returns 5 fancyObj['add'](2,3); // ditto.

As you can see, and probably already knew, properties can be accessed a couple of different ways. However, it’s an important point that we’ll come back to in a minute.

Everything in javascript is an object. Everything. Arraysfunctions, even numbers! Because of this, you can do some really interesting things, such as modifying the prototypes of Objects, Arrays, etc.

// an example of something you probably shouldn't do. Ever. Seriously.
Number.prototype.addto = function(x){
return this + x;
} (8).addto(9); // returns 17 // other variations: 8.addto(9); // gives a syntax error, because the dot is assumed to be a decimal point 8['addto'](9); // works but is kind of ugly compared to the first method var eight = 8;
eight.addto(9); // works

What Arrays Are

Javascript arrays are a type of object used for storing multiple values in a single variable. Each value gets numeric index and may be any data type.

var arr = [];  // this is a shortcut for new Array();
arr[0] = "cat";
arr[1] = "mouse";

See how that syntax is so similar to the syntax used for setting object properties? In fact, the only difference is that objects use a string while arrays use a number. This is why arrays get confused with objects so often.

Length

Arrays have a length property that tells how many items are in the array and is automatically updated when you add or remove items to the array.

var arr = [];
arr[0] = "cat"; // this adds to the array
arr[1] = "mouse"; // this adds to the array
arr.length; // returns 2 arr["favoriteFood"] = "pizza"; // this DOES NOT add to the array. Setting a string parameter adds to the underlying object
arr.length; // returns 2, not 3

The length property is only modified when you add an item to the array, not the underlying object.

The length is always 1 higher than the highest index, even if there are actually fewer items in the array.

var arr = [];
arr.length; // returns 0; arr[100] = "this is the only item in the array";
arr.length; // returns 101, even though there is only 1 object in the array

This is somewhat counter-intuitive. PHP does more what you would expect:

<?php
arr = array();
arr[100] = "php behaves differently";
sizeof(arr); // returns 1 in PHP
?>

You can manually set the length also. Setting it to 0 is a simple way to empty an array.

In addition to this length property, arrays have lots of nifty built in functions such as push()pop()sort()slice()splice(), and more. This is what sets them apart from Array-Like Objects.

Array-like Objects

Array-like objects look like arrays. They have various numbered elements and a length property. But that’s where the similarity stops. Array-like objects do not have any of Array’s functions, and for-in loops don’t even work!

You’ll come across these more often than you might expect. A common one is the arguments variable that is present inside of every js function.

Also included in the category are the HTML node sets returned by document.getElementsByTagName()document.forms, and basically every other DOM method and property that gives a list of items.

document.forms.length; // returns 1;
document.forms[0]; // returns a form element.
document.forms.join(", "); // throws a type error. this is not an array.
typeof document.forms; // returns "object"

Did you know you can send any number of arguments you want to a javascript function? They're all stored in an array-like object named arguments.

function takesTwoParams(a, b){
// arguments is an array-like variable that is automatically created
// arguments.length works great alert ("you gave me "+arguments.length+" arguments"); for(i=0; i&lt; arguments.length; i++){
alert("parameter " + i + " = " + arguments[i]);
}
} takesTwoParams("one","two","three");
// alerts "you gave me 3 arguments",
// then "parameter 0 = one"
// etc.
Tip: Parameters are the named variables in a function's signature: a and b in the previous example.
Arguments, by contrast, are the expressions that are used when calling the function: "one""two", and "three" in this case.

This works great. But that's about as far as you can go with array-like objects. The flowing example does not work:

function takesTwoParams(a, b){
alert(" your parameters were " + arguments.join(", "));
// throws a type error because arguments.join doesn't exist
}

So what can you do?

Well you could make your own join() function, but that adds a lot of unnecessary overhead to your code because it has to loop over everything. If only there were a quick way to get an array out of an array like object…

It turns out there is.

The array functions can be called on non-array objects as long as you know where to find the function (usually they’re attached to the array, but this isn’t an array remember 

Prototype to the win:

function takesTwoParams(a, b){
var args = Array.prototype.slice.call(arguments);
alert(" your parameters were " + args.join(", "));
// yay, this works!
}

Let’s take a look at that a bit more in-depth:

Array: This object is the original array that all other arrays inherit their properties from.

Array.prototype:This gives us access to all the methods properties that each array inherits

Array.prototype.slice: The original slice method that is given to all arrays via the prototype chain. We can’t call it directly though, because when it runs internally, it looks at the this keyword, and calling it here would make this point to Array, not our arguments variable.

Array.prototype.slice.call()call() and apply() are prototype methods of the Function object, meaning that they can be called on every function in javascript. These allow you to change what the this variable points to inside a given function.

And finally, you get a regular array back! This works because javascript returns a new object of type Array rather than whatever you gave it. This causes a lot of headaches for a few people who are trying to make subclasses of Array, but it’s very handy in our case!

Gotchas

First, in Internet Explorer, DOM NodeLists are not considered to be javascript objects, so you cannot call Array.prototype.slice on them. If you want an array, you’ll have to loop through it the old fashioned way. Or use a hybrid function that tries it the fast way first, then the slow way if that doesn’t work.

function hybridToArray(nodes){
try{
// works in every browser except IE
var arr = Array.prototype.slice.call(nodes);
return arr;
} catch(err){
// slower, but works in IE
var arr = [],
length = nodes.length;
for(var i=0; i &lt; length; i++){
arr.push(nodes[i]);
}
return arr;
}
}

See an example here: http://nfriedly.com/demos/ie-nodelist-to-array.

Second, arrays are objects, so you can do this, but it can get you some serious inconsistencies:

arr = [];
arr[0] = "first element"; // adds item to the array
arr.length; // returns 1 arr.two = "second element"; // adds an item to the underlying object that array is built on top of.
arr.length; // still returns 1 ! // BUT...
for(i in arr){
// this will hit both 0 and "two"
}

Another solution: wrap arrays in an object if you need both worlds

This is basically a less efficient method of the array subclassing links I mentioned above. While less efficient, it has the advantage of being simple and reliable.

That said, I wouldn’t recommend that you use this in most cases due to issues with speed and extra code requirements. It’s provided here as an example.

// an example of a wrapper for an array.
// not recommended for most situations. var ArrayContainer = function(arr){
this.arr = arr || [];
this.length = this.arr.length;
}; ArrayContainer.prototype.add= function(item){
index = this.arr.length;
this.arr[index] = item;
this.length = this.arr.length;
return index;
}; ArrayContainer.prototype.get= function(index){
return this.arr[index];
}; ArrayContainer.prototype.forEach= function(fn){
if (this.arr.forEach) this.arr.forEach(fn);// use native code if it's there
else {
for(i in this.arr){
fn( i, this.arr[i], this.arr );
}
}
}; var mySuperDooperArray = new ArrayContainer();

Now that your array is (somewhat) protected on the inside, you can loop through it’s items with forEach() and know that they will match it’s length. You can also add arbitrary properties to ArrayContainer or mySuperDooperArray and they won’t get pulled into your forEach() loop.

This example could be extended to completely protect the array if the need arose.

An Even Better Solution: Hire a javascript expert.

nFriedly Web Development is a top ranked Javascript and AJAX ninja with an extensive portfolio of proven results. I can bring your project to life and make it run faster than you ever imagined. Get in touch with me or get a free instant estimate for new projects.

javascript array-like object的更多相关文章

  1. Javascript中判断变量是 array还是object(是数组还是对象)

    段文字是从github上截取由本人翻译过来的. 原文地址:https://github.com/nathansmith/javascript-quiz/blob/master/ANSWERS.md 怎 ...

  2. Javascript中判断变量是数组还是对象(array还是object)

    怎样判断一个JavaScript变量是array还是obiect? 答案: 1.如果你只是用typeof来检查该变量,不论是array还是object,都将返回‘objec'. 此问题的一个可行的答案 ...

  3. 不要将 Array、Object 等类型指定给 prototype

    在 JavaScript 中,注意不要将 Array.Object 等类型指定给 prototype,除非您的应用需要那么做.先观察如下代码: function Foo(){}Foo.prototyp ...

  4. javascript array操作

    首先来看一下怎么判断一个对象是不是数组: 1.Array.isArray(obj) 调用数组的isArray方法 2.obj instanceof Array 判断对象是否是Array的实例 3.Ob ...

  5. 【废弃中】JavaScript 内置Object

    创建: 2017/09/24 更新: 2018/01/22 增加window对象内容的链接 更改标题: [JavaScript 主要的自带Object] -> [JavaScript 内置Obj ...

  6. JavaScript:对Object对象的一些常用操作总结

    JavaScript对Object对象的一些常用操作总结. 一.Object.assign() 1.可以用作对象的复制 var obj = { a: 1 }; var copy = Object.as ...

  7. ExtJS学习-----------Ext.Object,ExtJS对javascript中的Object的扩展

    关于ExtJS对javascript中的Object的扩展.能够參考其帮助文档,文档下载地址:http://download.csdn.net/detail/z1137730824/7748893 以 ...

  8. JavaScript Array 對象

    JavaScript array 對象 array對象,是用於在單個變量中存儲多個值的一種變量類型. 創建array對象的語法: new array(); new array(size); new a ...

  9. 关于ExtJS对javascript中的Object的扩展

    关于ExtJS对javascript中的Object的扩展,可以参考其帮助文档,文档下载地址:http://download.csdn.net/detail/z1137730824/7748893 下 ...

  10. 最全总结 JavaScript Array 方法详解

    JavaScript Array 指南.png Array API 大全 (公众号: 前端自学社区).png 前言 我们在日常开发中,与接口打交道最多了,前端通过访问后端接口,然后将接口数据二次处理渲 ...

随机推荐

  1. 输入防抖 vue # 输入搜索的时候 及时搜索的快速访问接口的 解决方案 vue 中使用防抖和节流

    输入防抖 watch: { value (newVal, oldVal) { if (this.timer) { clearTimeout(this.timer) } this.timer = set ...

  2. 微信小程序---协同工作和发布

    (1)协同开发和发布 在中大型的公司里,人员的分工非常仔细,一般会有不同岗位角色的员工同时参与同一个小程序项目.为此,小程序平台设计了不同的权限管理使得项目管理者可以更加高效管理整个团队的协同工作. ...

  3. Eclipse启动的时候提示:Failed to load JavaHL Library

    版本信息: Eclipse Project Release Notes Release 4.7.3 启动提示: Subclipse talks to Subversion via a Java API ...

  4. NOI2018_Day1_T1_归程

    题目描述 本题的故事发生在魔力之都,在这里我们将为你介绍一些必要的设定. 魔力之都可以抽象成一个 n 个节点.m 条边的无向连通图(节点的编号从 1 至 n). 我们依次用 l,a 描述一条边的长度. ...

  5. Memcached的安装和应用

    Memcached的安装 1.安装libeventlibevent是一个事件触发的网络库,适用于windows.linux.bsd等多种平台,内部使用 select.epoll.kqueue等系统调用 ...

  6. svn搭建脚本

    1.yum install subversion 2.输入rpm -ql subversion查看安装位置 我们知道svn在bin目录下生成了几个二进制文件. 输入 svn --help可以查看svn ...

  7. MySQL账户管理和主从同步

    账户管理 在生产环境下操作数据库时,绝对不可以使用root账户连接,而是创建特定的账户,授予这个账户特定 的操作权限,然后连接进行操作,主要的操作就是数据的CRUD(增删改查) MySQL账户体系:根 ...

  8. LeetCode (32) Longest Valid Parentheses

    题目 Given a string containing just the characters '(' and ')', find the length of the longest valid ( ...

  9. 【NEFU 117 素数个数的位数】(素数定理)

    Description 小明是一个聪明的孩子,对数论有着很浓烈的兴趣. 他发现求1到正整数10n 之间有多少个素数是一个很难的问题,该问题的难以决定于n 值的大小. 现在的问题是,告诉你n的值,让你帮 ...

  10. Python数据结构--搜索树

    ''' 二叉搜索树(BST)是一棵树,其所有节点都遵循下述属性 - 节点的左子树的键小于或等于其父节点的键. 节点的右子树的键大于其父节点的键. 因此,BST将其所有子树分成两部分; 左边的子树和右边 ...