@JRuiCoder
2016-07-25T08:42:21.000000Z
字数 1425
阅读 1267
JavaScript
它看起来像是一个数组,而且它有一个length属性,然而它并不是一个数组。JavaScript有时候是一门很怪异的语言,因为你很难定义一个数组的概念而没有什么例外的。
所以我说的这些类数组对象是什么?它们有一些,其中包括arguments,arguments是一个很特殊的变量,你再所有函数体内都可以访问到。
假如你再一个工具(firebug)中检查arguments这个变量,你会注意到它打印出来像是一个数组。它有按次序排列的元素,还有一个length属性。
var testFunction = function() {console.log(arguments);console.log(arguments.length);};
所以我在抱怨什么?尝试arguments.shift(),报错显示arguments.shift() isn't a function,但是shift()是数组的一个函数。尝试console.log(arguments.constructor),它会打印Object(),同时假如你输入的是[].constructor,它会打印Array[]。这是不是很奇怪?
这当然不仅局限于arguments,看起来很多DOM集合都会返回这种对象,例如document.getElementsByTagName(), document.images, document.childNodes.在某些情况下,这些类似数组的更适合转变为一个数组。
当然这个标题是不太准确的,假如我们需要将这些类数组对象变成数组一样,我们需要建立一个新的数组。
var testFunction = function() {// Create a new array from the contents of argumentsvar args = Array.prototype.slice.call(arguments);var a = args.shift();console.log("The first argument is: %s", a);// send the remaining arguments to some other functionsomeOtherFunction(args);};
显然,关键的地方在Array.prototype.slice.call(arguments),拆开它仔细每个部分。
Array
这是我们想要的base object的名称
prototype
这可以被认为是一个数组实例方法的命名空间
slice
提取一个数组的一部分,并返回一个新的数组,没有一个开始和结束索引,它只返回数组的副本.
call
这是一个非常有用的函数,允许你在调用一个对象的函数,然后在另一个函数的上下文中使用
另一个方面,如果你曾经使用原型框架,你可以通过$A()转化这些类数组对象成为数组。
谈到$A,如果你不喜欢打上面那么长的字符串代码,并且你不使用Prototype。然后,你可以创建一条捷径,就像Prototype folks:
var $A = function(obj) {return Array.prototype.slice.call(obj);};// Example usage:$A(document.getElementsByTagName("li"));