程序员最近都爱上了这个网站  程序员们快来瞅瞅吧!  it98k网:it98k.com

本站消息

站长简介/公众号

  出租广告位,需要合作请联系站长


+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

集合引用类型篇(一)

发布于2021-04-09 07:11     阅读(505)     评论(0)     点赞(7)     收藏(3)


ECMAScript中最常用的集合引用类型就是ObjectArray,尤其是Array提供的很多方法,可以更方便的操纵数据,为我们提供快速处理数据的能力

Object

显示创建Object的实例对象有两种方法,一种是new Object()来实例化一个对象,另一种是使用对象字面量形式

在使用对象字面量表示法定义对象时,其实并没有调用Object()构造函数

Array

有几种方式可以创建数组,一种是数组字面量,一种是通过new关键字调用但不传递参数或者传递参数,也可以直接使用Array()创建,在ES6中新增了两个静态方法创建数组:Array.fromArray.of

let a = []
let a1 = [1, 2,]
let a2 = [, 1, 2]
console.log(typeof a1) //'object' //没有array数据类型哟
console.log(a1.length) //2 不是3
console.log(a2.length) //3 空位在前,算一个长度

let a2 = new Array()
console.log(typeof a2) //'object'
console.log(a2.length) //0

let a3 = new Array(20)
console.log(typeof a3) //'object'
console.log(a3.length) //20

let a4 = Array(20)
console.log(typeof a4) //'object'
console.log(a4.length) //20

//传递参数有一个问题,如果是数值,会变成新建数组的长度,如果是其他类型的值,会成为数组的初始值
let a5 = new Array(20)
let a6 = new Array('red')
console.log('a5', a4, 'a5 length', a5.length) //a5 [empty × 20] a5 length 20
console.log('a6', a5, 'a6 length', a6.length) //a6 ["red"] a6 length 1

与对象一样,在使用数组字面量表示法创建数组不会调用Array构造函数。

Array.from 和Array.of

Array.from()用于将类数组结构转换成数组,类数组类结构即可迭代的结构,或者有一个length属性和可索引元素的结构

Array.of()用于将一组参数转换成数组,替代之前的Array.prototype.slice.call(arguments)

//Array.form 
console.log(Array.from('解构字符串为数组')) //["解", "构", "字", "符", "串", "为", "数", "组"]
console.log(Array.from(new Map([['a', 1], ['b', 2]]))) //[['a', 1], ['b', 2]]
console.log(Array.from(new Set(['a', 'b', 'c', 'd']))) //["a", "b", "c", "d"]

//对现有数组进行浅复制
let a = [1, 2, {a: 3}]
let b = Array.from(a)
console.log(a === b) //false
b[2].a = 6
console.log(a) //[1, 2, {a: 6}]

//实现了Symbol.iterator的结构
const iter = {
  *[Symbol.iterator]() {
    yield 1
    yield 3
  }
}
console.log(Array.from(iter)) //[1, 3]

//自定义对象转换为数组
const obj = {
  1: 'aaa',
  2: 'bbb',
  length: 2 //有length属性
}
console.log(Array.from(obj)) //[undefined, 'aaa']

Array.from()还可以接收第二个可选的映射函数参数。直接增强数组的值

let a = Array.from('123456', x => x * 2)  //对返回的数组调用回调函数并返回值,类似于Array.prototype.map()
console.log(a) //[2, 4, 6, 8, 10, 12]

Array.from()的第三个参数用于绑定,第二个函数中的this

数组空位

可以使用一串逗号来创建空位,ES6方法普遍将空位当成undefinedECMAScript` 会将逗号之间相应索引位置的值当成空位。

const options = [,,,,,]; // 创建包含 5 个元素的数组 
console.log(options.length); // 5 
console.log(options); // [,,,,,]

const anotherOptions = [1,,,,5];
// map()会跳过空位置
console.log(anotherOptions.map(() => 6)); // [6, undefined, undefined, undefined, 6]
// join()视空位置为空字符串 
console.log(anotherOptions.join('-')); // "1----5"

由于行为不一致和存在性能隐患,因此实践中要避免使用数组空位。如果确实需要 空位,则可以显式地用 undefined 值代替。

数组索引

可以使用中括号取得数组的值

数组的length属性是可写的,也就意味着可以通过直接给length赋值来改变数组的长度,从而添加或删除末尾的值

let colors = ["red", "blue", "green"]; // 创建一个包含 3 个字符串的数组 
colors.length = 2;
console.log(colors[2]); // undefined

检测数组

对于只有一个全局作用域的情况下,可以使用instanceof操作符

let isArray = value instanceof Array //true 是数组,false 不是数组

对于不止一个全局作用域的情况下,使用Array.isArray()

let isArray = Array.isArray(value) //true 是数组,false 不是数组

Array.isArray方法的目的就是确定一个值是否为数组,而不用管它是在哪个全局执行上下文中创建的,因此优先推荐

当然也可以使用Object.prototype.toString.call()

迭代器方法

ES6Array的原型上新增了用于检索数组的方法:values()keys()entries()values()返回数组元素的迭代器,keys()返回数组索引的迭代器,entries()返回数组的索引/值对的迭代器

let a = ['a', 'b', {c: 2}]

console.log(a.values()) //Iterator {}
console.log(a.keys()) //Iterator {}
console.log(a.entries()) //Iterator {}
console.log(Array.from(a.values())) //["a", "b", {c: 2}]
console.log(Array.from(a.keys())) //[0, 1, 2]
console.log(Array.from(a.entries())) //[[0, "a"], [1, "b"], [2, {c: 2}]]

复制和填充方法

ES6新增了copyWithin()fill(),用于复制和填充数组

copyWithin()第一个参数指定要插入的位置,第二个参数为截取数组开始位置,默认为0,第三个参数为截取数组结尾位置,默认为数组长度。会静默忽略超出边界、零长度及方向相反的索引

//会改变原始数组的值
let a = [1, 2, 3, 4, 5, 6]
a.copyWithin(3) //[1, 2, 3, 1, 2, 3] //将a[0]到a[a.length - 1]的元素复制到a[3]
a.copyWithin(3, 2) //[1, 2, 3, 3, 1, 2] //将a[2]到a[a.length - 1]的元素复制到a[3]
a.copyWithin(3, 2, 4) //[1, 2, 3, 3, 3, 2] //将a[2]到a[4]的元素复制到a[3]
a.copyWithin(3, -5, -3) //[1, 2, 3, 2, 3, 3] //将a[1]到a[3]的元素复制到a[3]

fill()可以向一个已有的数组中插入全部或部分相同的值,fill()也会静默忽略超出数组边界、零长度及方向相反的索引范围

//会改变原始数组的值
let a = [1, 2, 3, 4]
a.fill(5) //[5, 5, 5, 5]
a.fill('a', 3) //[5, 5, 5, "a"]
a.fill('b', 1, 3) //[5, "b", "b", "a"]

转换方法

所有对象都有valueOf()toString()toLocaleString()方法。数组的valueOf()方法返回数组本身,toString()返回每个等效元素字符串拼接而成的一个逗号分隔的字符串

let a = [1, 'a', {b: 'sss'}, [2, 3]]
console.log(a.valueOf()) //[1, "a", {b: 'sss'}, Array(2)]
console.log(a.toString()) //"1,a,[object Object],2,3"
console.log(a.toLocaleString()) //"1,a,[object Object],2,3"

如果想用不同的符号插入到没有元素之间,可以使用join()方法

let a = [1, 'a', {b: 'sss'}, [2, 3]]
console.log(a.join()) //1,a,[object Object],2,3 //默认返回以逗号分隔的字符串
console.log(a.join('--')) //1--a--[object Object]--2,3

栈方法和队列方法

push()pop()用于在数组末尾添加多个或删除一个元素,shift()unshift()用于在数组开头删除一个或添加多个元素

let a = []
let b = a.push('a', 'b', 'c', 'd')
//push()方法接收多个值,返回插入的个数
console.log('array:', a, 'b:', b) //"array: ["a", "b", "c", "d"] b: 4"
let c = a.pop()
//pop()方法返回删除的元素
console.log('array:', a, 'c:', c) //"array: ["a", "b", "c"] c: d"

let m = []
let n = m.unshift('m', 'n')
//unshift()方法接收多个值,返回插入的个数
console.log('array:', m, 'n', n) //"array: ["m", "n"] n 2"
let t = m.shift()
//shift()方法返回删除的元素
console.log('array:', m, 't', t) //"array: ["n"] t m"

排序方法

reverse() 用于将数组元素反向排序,sort()默认情况下按照升序排列数组元素,sort()会为元素的每一项调用String()转型函数,然后比较字符串来决定顺序

let a = [1, 2, 3, 4, 10]
a.reverse()
console.log(a) //[10, 4, 3, 2, 1]

//sort()
let a = [1, 2, 10, 3]
a.sort()
console.log(a) //[1, 10, 2, 3] ??好像发生了什么问题,其实是因为,sort将每个元素转换成了字符串再进行比较排序,而"10"和"2"进行比较时,由于"10"在"2"的前面所以会排在前面
//所以给sort()传入一个函数,自定义比较排序
a.sort(function (value1, value2) {
  if (value1 < value2) {
    return -1
  } else if (value1 > value2) {
    return 1
  }
  
  return 0
});
console.log(a) //[1, 2, 3, 10]
//return -1时,value1排在value2的前面, return 1时, value1排在value2的后面,return 0时,两个值相等

reverse()和sort()都返回调用它们的数组的引用。都会改变原始数组

操作方法

concat()

用于将一个或多个值拼接在数组末尾,并返回一个新数组,是浅复制。默认会打平数组,打平等级为1

let a = [1, 2, 3]
let b = a.concat(5, 'red', ['blue', 6, ['8', 9]])
console.log(a) //[1, 2, 3]
console.log(b) //[1, 2, 3, 5, "red", "blue", 6, ['8', 9]] //传递的数组被打平了,但只打平1级

可以设置Symbol.isConcatSpreadable属性来改变打平数组参数的行为

let a = [1, 2, 3]
let b = ['red', 'blue']
b[Symbol.isConcatSpreadable] = false
console.log(a.concat(b)) //[1, 2, 3, ["red", "blue"]]
//也可以处理类数组
let c = {
  length: 2,
  0: 1,
  1: "red",
  [Symbol.isConcatSpreadable]: true
}

console.log(a.concat('c', c)) //[1, 2, 3, "c", 1, "red"]

slice()

用于从原始数组中获取指定长度的数组片段

let a = [1, 2, 3, 4, 5]
a.slice() //默认从开始到数组末尾 a[0] ~ a[a.length],左闭右开,下同
a.slice(2) //从a[2] ~ a[a.length]
a.slice(2, 4) //从a[2] ~ a[4]
a.slice(-2) //从a[a.length - 2] ~ a[a.length] //负值为,数组长度加这个负值

splice()

splice()可以实现删除,插入和替换,返回删除的元素组成的数组,没有删除返回空数组

let a = [2, 3, 4, 5]
//删除
a.splice(1, 1) //[3]  //从索引1处的元素开始,删除一个元素
console.log(a) //[2, 4, 5]

//插入
a.splice(1, 0, 'red', 'blue') //[] //从索引1处的元素开始,添加两个元素
console.log(a) //[2, "red", "blue", 4, 5]

//替换
a.splice(1, 1, 'green') //["red"] //从索引1处的元素开始,删除一个元素,同时添加一个元素
console.log(a) //[2, "green", "blue", 4, 5]

搜索与位置方法

严格相等

indexOf()lastIndexOf()includes(),用于搜索指定字符串是否存在。

indexOf()从数组起始开始搜索,第一个参数为搜索的元素,第二个参数为搜索的起始位置,如果存在返回元素位置,如果不存在返回-1

let a = [1, 2, 3, 4, 2, 5]
let index = a.indexOf(2)
console.log(index) //1
index = a.indexOf(2, 3)
console.log(index) //4

lastIndexOf()从数组末尾开始搜索,第一个参数为搜索的元素,第二个参数为搜索的起始位置,如果存在返回元素位置,如果不存在返回-1

let a = [1, 2, 3, 4, 2, 5]
let index = a.lastIndexOf(2)
console.log(index) //4
index = a.lastIndexOf(2, 3)
console.log(index) //1

includes()从数组起始开始搜索,第一个参数为搜索的元素,第二个参数为搜索的起始位置,返回布尔值,表示是否至少找到一个与指定元素匹配的项

let a = [1, 2, 3, 4, 2, 5]
let index = a.includes(2)
console.log(index) //true
index = a.includes(2, 5)
console.log(index) //false

断言函数

find()findIndex()方法使用了断言函数。这两个方法都从数组的最小索引开始。find()返回 第一个匹配的元素,findIndex()返回第一个匹配元素的索引

const people = [
  {
    name: "Matt",
    age: 27 
  },
  {
    name: "Nicholas",
    age: 29
	} 
];
// find()找到匹配后,永远不会检查数组的最后一个元素
people.find((element, index, array) => element.age < 28)  // {name: "Matt", age: 27}
people.findIndex((element, index, array) => element.age < 28) //0

迭代方法

every() 对数组每一项都运行传入的函数,如果对每一项函数都返回true,则这个方法返回 true

filter()对数组每一项都运行传入的函数,函数返回 true 的项会组成数组之后返回。
forEach()对数组每一项都运行传入的函数,没有返回值。
map()对数组每一项都运行传入的函数,返回由每次函数调用的结果构成的数组。

some()对数组每一项都运行传入的函数,如果有一项函数返回 true,则这个方法返回 true

//every()
let a = [1, 3, 5, 7]
console.log('输出')
let a1 = a.every(function (el, i, array) {
  console.log(i)
  return el < 5
})
console.log(a1)
//输出
//0
//1
//2
//false

//some()
let a = [1, 3, 5, 7]
console.log('输出')
let a1 = a.some(function (el, i, array) {
  console.log(i)
  return el > 3
})
console.log(a1)
//输出
//0
//1
//2
//true

every()some()结果确立后,将不会继续往下执行

归并方法

reduce()reduceRight()这两个方法都会迭代数 组的所有项,并在此基础上构建一个最终返回值。reduce()方法从数组第一项开始遍历到最后一项。 而 reduceRight()从最后一项开始遍历至第一项。

//没有第二个参数时
let values = [1, 2, 3, 4, 5];
let sum = values.reduce((prev, cur, index, array) => prev + cur);
console.log(sum) //15

//有第二个参数时
let values = [1, 2, 3, 4, 5];
let sum = values.reduce((prev, cur, index, array) => prev + cur, 10);
console.log(sum) //25



所属网站分类: 技术文章 > 博客

作者:我喜欢css

链接:http://www.qianduanheidong.com/blog/article/58534/cf2c60f98904a367bfd3/

来源:前端黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

7 0
收藏该文
已收藏

评论内容:(最多支持255个字符)