在最新的TypeScript 3.6中实现了更准确的数组扩展。借此机会聊一下我对js中数组的一点理解。
使用Array()初始化数组
先来看一下下面的两行代码
1 in [undefined, undefined, undefined] // true
1 in Array(3) // false
再看一下接下来代码
let arr=new Array(3).map(()=>{return 3})
console.log(arr) //(3) [empty × 3]
可见使用无论使用Array方法还是使用Array构造器所生成的数组均为没有索引与元素单存在length属性的空数组。(参数为单个非负整数时)
map方法对于没有赋值或者被delete删除的索引不会调用
初始化数组
以下三种方法都可以得到一个[undefined, undefined, undefined]数组
Array(...Array(3))
Array.apply(null,Array(3))
Array.apply(null,{length:3})
第一种第二种方法比较好理解,但是第三种apply方法的第二个参数为数组为什么传入一个对象同样可以执行。据我测试后发现ie8及以下版本中会直接报错,chrome、firefox、edge、ie9-11中可以执行。目前大部分浏览器都支持apply传入一个类数组对象。有些文章中称是因为{length:3}为一个可迭代方法,实际上是错误的说法,对象是否可迭代实际上是由对象及其原型链上是否存在[Symbol.iterator]方法决定的。调用该方法可以得到一个对象的迭代器,调用对象的keys方法也可以得到一个相同的迭代器
[1,2,3][Symbol.iterator]()
[1,2,3].keys()
另外enumerable为false的属性无法被keys、for in 、entries枚举。
let tempArr=[1,2,3]
Object.defineProperty(tempArr,'0',{enumerable:false})
for(let i in tempArr){
console.log(tempArr[i])
} //2 3
Object.keys(tempArr) //(2) ["1", "2"]
Object.entries(tempArr) //(2) [["1", 2],["2", 3]]