js 数组/关联数组 和 类数组对象/伪数组

629 阅读3分钟

1数组

1.1 索引数组/普通数组

普通数组是对象,typeof只返回js固定的基本数据类型,数组是Object引用类型

var users = ["张三", "李四", "王五"]; 
console.log(typeof users); // object

数字索引访问

var users = ["张三", "李四", "王五"]; 
console.log(users[1]); // 李四

数组元素可以是对象

let user1 = {name:张三, age:19}
let user2 = {name:李四, age:20}
var users = [user1, user2]; 
console.log(users[1]); // {name:李四, age:20}

可设置 length

let a = [1,2,3]
a.length = 6;
console.log(a)
//(6) [1, 2, 3, empty × 3]
//0: 1
//1: 2
//2: 3
//length: 6
//__proto__: Array(0)

包含Array类型的所有方法 push pop 等

let a = [1,2,3]
a.push(4)
a.push(5)
a.pop()

遍历 (所有for都可以)

for 和 for of 和for in , forEach,map 都可以

var users = ["张三", "李四", "王五"]; 
for(key in users){
    console.log(users[key])
}
for(user of users){
    console.log(user)
}
users.forEach(user => {
    console.log(user)
});
users.map(user => {
    console.log(user)
});

1.2关联数组

js底层数据结构使用关联数组

关联数组:可以使用字符串索引数据的数组,当输入非数字,会打破数组原来的规则,比如length已经不准确

关联数组依然持有Array的所有内置方法

访问方式

  1. 数字索引
var users = []; 
users["0"] = "张三"
users["1"] = "李四"
users["2"] = "王五"
console.log(users[0]) //张三
console.log(users[1]) //李四
console.log(users[2]) //王五
  1. 命名索引
var users = []; 
users["zhangsan"] = "张三"
users["lisi"] = "李四"
users["wangwu"] = "王五"
console.log(users["zhangsan"]) //张三
console.log(users["lisi"]) //李四
console.log(users["wangwu"]) //王五
console.log(users.length) //长度为 0

3.变量方式

var users = [];  
users["zhangsan"] = "张三"
users["lisi"] = "李四"
users["wangwu"] = "王五"
var key = "zhangsan"
console.log(users[key]) //张三 
  1. 对象.xxx
var users = [];  
users["zhangsan"] = "张三"
users["lisi"] = "李四"
users["wangwu"] = "王五"
console.log(users.zhangsan) //张三
console.log(users.lisi) //李四
console.log(users.wangwu) //王五

原理

通过hash函数,把当前的key值运算后访问下标,再去访问数组。

遍历 (for in)

只能用无序的 for in 遍历key的方式获取值

var users = []; 
users["0"] = "张三"
users["1"] = "李四"
users["wangwu"] = "王五"
for(key in users){
    console.log(users[key])
}
//张三
//李四
//王五

不能用for of ,下面代码会遍历少了王五

var users = []; 
users["0"] = "张三"
users["1"] = "李四"
users["wangwu"] = "王五"
for(a of users){
    console.log(a)
}
//张三
//李四 

1.3 js只有一种数组:关联数组

在索引数组里的数字索引0,1,2,3,4 其实底层还是使用字符串索引"0","1","2","3","4"

所以数组都是关联数组

//索引数组
var users = ["张三", "李四", "王五"];  
//最终会转化成下面的关联数组
//关联数组
var users = []; 
users["0"] = "张三"
users["1"] = "李四"
users["2"] = "王五" 

上面两种写法底层实现都是一样的,关联数组

2.类数组对象/伪数组

类数组对象又叫:伪数组 ,如js函数参数 arguments,下标都是确定有序的,和索引数组类似,但是又没有Array的方法

例如:

function test() {
    console.log(arguments)
}
test(1,2,3,4,"张三")
// Arguments(5) [1, 2, 3, 4, '张三', callee: ƒ, Symbol(Symbol.iterator): ƒ]
// 0: 1
// 1: 2
// 2: 3
// 3: 4
// 4: "张三"
// callee: ƒ test()
// length: 5
// Symbol(Symbol.iterator): ƒ values()
// [[Prototype]]: Object

定义

let users = {0:"张三", 1:"李四", 2:"王五","length": 3}

具有

  • 长度
  • 可遍历

没有

  • 数组的方法pop,push等

遍历 (for 和 for of 和for in)

for 和 for of 和for in 都可以

forEach不行

function test() { 
    for (let i = 0; i < arguments.length; i++) { 
        console.log(arguments[i])
    }
    for (const key of arguments) {
        console.log(key)
    }
    for (const key in arguments) {
        console.log(arguments[key])
    }
    
    arguments.forEach((o) => { //这里会报错 Uncaught TypeError: arguments.forEach is not a function
        console.log(o)
    })
     arguments.map((o) => { //这里会报错 Uncaught TypeError: arguments.forEach is not a function
        console.log(o)
    })
}
test(1,2,3,4,"张三")

3类数组对象转数组

1. Array.from

function transform() {
  let arr = Array.from(arguments)
}
transform(1,2,3)

2. Array.prototype.slice.call

function transform() {
 let arr = Array.prototype.slice.call(arguments) 
}
transform(1,2,3) 

3.展开...

function transform() {
   let arr = [...arguments]
   console.log(arr) // [1, 2, 3] 
}
transform(1,2,3)