伪数组
- 伪数组是一个对象(Object),而真实的数组是一个数组(Array)
- 拥有length属性,且必须是number类型,其它属性(索引)为字符串
- 不具有数组所具有的方法,forEach()等,不过有Object的方法
- 伪数组长度不可变,真数组长度可以变
- 可以通过for in遍历
var fakeArray = {
length: 3,
"0": "first",
"1": "second",
"2": "third"
}
var arr = [1, 2, 3, 4]
// 真数组的方法来自Array.prototype
console.log(fakeArray instanceof Array) //false
console.log(arr instanceof Array) // true
Array.isArray(fakeArray) // false;
Array.isArray(arr) // true;
console.log(arr.__proto__ === Array.prototype) // true
console.log(fakeArray.__proto__ === Array.prototype) // false
console.log(fakeArray.__proto__ === Object.prototype) // true
arr.forEach(x => console.log(x)) // 1 2 3 4
fakeArray.forEach(x => console.log(x)) // fakeArray.forEach is not a function
Object.keys(fakeArray) // ["0", "1", "2", "length"]
常见的伪数组
- 参数数组:arguments
- DOM对象列表HTMLCollection():比如通document.getElementsByTagName得到的列表
- jquery对象:比如$(“div”)
伪数组转换为真数组
1.使用Array.prototype.slice.call();
var fakeArray = {
length: 3,
"0": "first",
"1": "second",
"2": "third"
}
// 将伪数组转换为真数组
var arr = Array.prototype.slice.call(fakeArray)
console.log(arr) // ["first", "second", "third"]
Array.isArray(arr) // true
console.log(arr instanceof Array) // true
arr.forEach(x => console.log(x)) // first second third
2. 使用[].slice.call()
var fakeArray = {
length: 3,
"0": "first",
"1": "second",
"2": "third"
}
var arr = [].slice.call(fakeArray)
console.log(arr) // ["first", "second", "third"]
3. 使用ES6中的Array.from方法
var fakeArray = {
length: 3,
"0": "first",
"1": "second",
"2": "third"
}
var arr = Array.from(fakeArray)
console.log(arr) // ["first", "second", "third"]
4.使用扩展运算符,也是ES6的语法
var fakeArray = document.querySelectorAll('div')
var newArr= [...fakeArray]
console.log(newArr.__proto__ === Array.prototype) // true
伪数组转换为真数组原理
Array.prototype.slice = function (start, end) {
start = start || 0
end = start || this.length
const arr = []
for (var i = start; i < end; i++) {
arr.push(this[i])
}
return arr
}