JavaScript - 数组和类数组对象的区别
JavaScript中的数组和类数组对象之间的区别是什么?为什么会出现这个问题?如何解决?
首先,数组是一种特殊的对象。它具有以下特点:
- 有一个特殊的字面量语法`[ … ]`
- 有一个自动更新的`length`属性
- 数组原型包含了通常从数组中期望的函数
另一个明显的特点是,所有的元素都有一个数值索引。
从JavaScript的角度来看,任何具有`length`属性的对象都足够接近被视为类数组对象:
var arrayLikeObject = { length: 3, name: 'thing', '1': 'hello' }; console.log(arrayLikeObject);
`length`属性不一定要正确。即使在一个正常的数组中,也有可能强制`length`不等于实际元素的数量。缺失的元素都会返回`undefined`。
你可以使用`Array.from()`将类数组对象转换为真正的数组。这个函数可以接受各种值,但最简单的是像这样:
var arrayLikeObject = { length: 3, name: 'thing', '1': 'hello' }; var array = Array.from(arrayLikeObject); console.log(array);
从此以后,数组就具有了所有通常的属性和方法。在上面的示例中,属性`[1]`被复制到新数组中,但元素`[name]`则不会,因为它不属于真正的数组。
`Array.from()`函数还可以接受一个映射函数作为第二个参数。这样可以在转换过程中进行任何所需的更改:
var arrayLikeObject = { length: 3, name: 'thing', '1': 'hello' }; var array = Array.from(arrayLikeObject, (element,index) => element?element.toUpperCase():`Item ${index}` ); console.log(array);
JavaScript中数组和类似数组对象之间的区别
在JavaScript中,有一些对象被称为类似数组对象,它们具有类似于数组的特性。然而,它们与真正的数组之间存在一些区别。本文将探讨这些区别以及如何解决这些问题。
类似数组对象是自动创建的,其中包括著名的HTMLCollection和arguments对象。下面是一些真正的数组和类似数组对象之间的快速比较示例:
var realArray = ['value1', 'value2']; var arrayLike = document.forms;
相似之处:
- length属性的获取方法相同:
arrayLike.length; // 返回2 realArray.length; // 返回2
- 索引获取方法相同:
arrayLike[0]; // 返回一个元素 realArray[0]; // 返回一个元素 ('value')
- 它们都是对象:
typeof arrayLike; // 返回"object" typeof realArray; // 返回"object"
不同之处:
- 在类似数组对象中,join()、concat()、includes()等方法不是函数:
arrayLike.join(", "); // 报错:Uncaught TypeError: arrayLike.join is not a function (其他方法如concat()、includes()等也是一样) realArray.join(", "); // 返回"value1, value2"
- 类似数组对象并不是真正的数组:
Array.isArray(arrayLike); // 返回false Array.isArray(realArray); // 返回true
- 在类似数组对象中无法设置length属性:
arrayLike.length = 1; arrayLike.length; // 返回2,因为DOM中有两个表单 realArray.length = 1; realArray.length; // 返回1
通过以上内容,我们可以看出,虽然类似数组对象在某些方面与真正的数组相似,但它们在方法的调用和属性的设置上存在一些限制。因此,如果需要使用数组特有的方法和属性,需要将类似数组对象转换为真正的数组。
解决这个问题的方法是使用Array.from()方法或者展开运算符(...)将类似数组对象转换为真正的数组。例如:
var realArray = Array.from(arrayLike); var realArray = [...arrayLike];
通过这些方法,我们可以将类似数组对象转换为真正的数组,并使用数组的方法和属性来操作数据。这样,我们就能够充分发挥JavaScript中数组的功能了。
JavaScript中的Array和Array-like object之间的区别是什么?为什么会出现这个问题?解决方法是什么?
Array-like object是指具有非负整数的length属性和通常具有一些索引属性的对象。它们通常不是由Array构造函数或者使用Array字面量[]创建的,因此(通常)不会继承自Array.prototype,length属性也不会自动更新。
我们可以使用Array.prototype.slice将Array-like object转换为Array。只需要调用Array.prototype.slice方法并传入要转换的Array-like object即可。
与普通对象相比,Array-like object并没有什么区别。在JavaScript中,普通的Array也是对象。
关于"usually"部分的解释是:如果一个对象继承自Array.prototype,那么它不是Array-like object,而是一个Array。可以通过Array.isArray方法来判断一个对象是否是Array。
在ES5-版本中,如果使用ES5-的方式设置自定义对象的原型,将得到Array-like object。而在ES6+版本中,如果使用class和super关键字设置原型,将得到Array。
所以,区分Array-like object和Array的关键在于length属性是否会自动更新。如果一个对象具有Array的方法(通过继承Array.prototype实现),并且具有length属性以及数字索引,那么它就是一个Array,而不是Array-like object。
关于为什么不能使用Array.prototype.sort方法对Array-like object进行排序的问题,是因为Array-like object没有length属性。只有具有length属性的对象才能被认为是Array-like object。
总结一下,Array和Array-like object之间的区别在于是否具有length属性以及是否继承自Array.prototype。如果想要将Array-like object转换为Array,可以使用Array.prototype.slice方法。