ES6新数组方法

介绍
在发布ES6之后,我已经看到许多开发人员仍然不知道该Array对象最近添加的功能。因此,我决定创建这篇文章来传播信息,并希望许多人将从中受益。

背景
本文不是关于JavaScript数组的介绍,而是有关研究Array对象的新添加功能的更多内容。如果您是初学者,我建议您进行Google搜索。而且,在我看来,这些附加功能确实有目标。并且,其中之一是使我们的生活变得更轻松,并在处理该Array物体时多产。最后,如果您对数组有很好的了解,则可以轻松阅读本文。

ECMAScript 6增强型阵列
如前所述,ECMAScript 6(ES6)已向全局Array对象添加了新方法。因此,我们将讨论以下方法:

Array.from()
Array.of()
copyWithin()
fill()
find()
findIndex()
entries()
keys()
values()

因此,让我们开始吧。我希望你很兴奋。

Array.from()方法
这是一种从可迭代对象static返回新Array实例的方法。但是,您也可以在第一个参数中传递“类似数组的对象”。如果您对此尚不了解,将在本节中进行讨论。

句法
隐藏 复制代码
//syntax
//Array.from(arrayLike[, mapFn[, thisArg]]);
参量
arrayLike –是可迭代对象的引用。
mapFn –是可选的,并充当称为map-function的回调。
thisArg–也是可选的,并且是thismap函数内部的值。

隐藏 复制代码

let result = 
Array.from('JavaScript', (val, indx) => `[${
    
    indx}]` + "=>" + val.toUpperCase());

console.log(result);

输出量

如您所见,上面的示例很容易理解。

功能
这是第二个参数(如果提供),在调用时将充当映射回调。并且,它将每个值从源转换为返回的目标。
这类似于 Array.prototype.map() 方法。
现在,为什么不看看另一个示例,您认为呢?而且,为什么不把它Array.from()放在里面呢Object。从而,我们可以看到映射回调函数和第3个参数的this行为。

const manager = {
    
    
  isBadManager: true,
  doBadStuff: function (items) {
    
    
    return Array.from(items, function (val, indx) {
    
    

      if (this.isBadManager) {
    
    
        console.log(`${
    
    indx + 1}. ${
    
    val[0].toUpperCase()}${
    
    val.substr(1)}`);
      }
    }, this);
  }
}

/**
 * Output:
 *  1. That's my idea
 *  2. Micromanage
 */

manager.doBadStuff([‘that’s my idea’,‘micromanage’]);
同样,易于遵循的示例。现在,让我们提高一个档次。并且,让我们更多地关注的第一个 参数,Array.map()它是类似数组的对象(arrayLike)。

什么是类似数组的对象?
通常,您会在JavaScript中遇到一些看起来像数组的对象,通常称为“类似数组的对象”。困惑?不用了 它object的长度属性为非负整数,并且具有一些索引属性。

让我们看下面的例子:

let arrLike1 = {
    
    
  length: 3,
  0: "Jin",
  1: "Vincent",
  2: "Necesario"
};

而已?是!

现在,让我们看一下如何使用将arrLike1变量转换为实数。ArrayArray.from()

let resultArray2 = Array.from(arrLike1);

console.log(resultArray2); 
//output: ["Jin", "Vincent", "Necesario"]

节点列表
ANodeList是类数组对象的另一个示例。甚至我也挣扎着NodeList。我以为是数组,但不是。

NodeList和Arrays 完全不同的东西。

好,那是NodeList什么?甲NodeList目的是集合DOM这是从所提取的节点HTML使用浏览器时文件API诸如querySelector()和/或querySelectorAll()。

现在,我们有一个想法,什么NodeList是,让我们尝试将转换NodeList到Array与使用Array.from()。

<!-- this is the html file -->
<body>
    <div>
        <p>Hello World 1</p>
        <p>Hello World 2</p>
        <p>Hello World 3</p>
    </div>
</body>
/**
 * Start of NodeList
 * In this code sample we will see what a NodeList is. 
 * Here are some facts about NodeList. 
 * 
 * 1. NodeList aren't arrays. 
 * 2. NodeList does have a length property
 * 3. NodeList does have indexed property
 * 4. Therefore, we can conclude that a NodeList does look like
 *    an Array-like object.
 * 5. We can convert NodeList into an array with the use of Array.from()
 */
window.addEventListener("DOMContentLoaded", function (event) {
    
     

  let elements = document.querySelectorAll("div p");

  console.log(elements); //output: NodeList(3) [p, p, p]

  //this proves that NodeList does have a length property
  console.log(elements.length) //output: 3

  console.log(typeof (elements)); //output: object
  
  //this proves that the return of querySelectorAll method is a NodeList
  console.log(elements instanceof NodeList); //output: true

  //this proves that NodeList aren't arrays
  console.log(elements instanceof Array); //output: false

  let arrayParagraphs = Array.from(elements);

  console.log(arrayParagraphs); //output: Array(3)

});
 /**
  * End of NodeList
  */

既然我们熟悉了类似数组的对象,并且已经了解了如何将其转换为真实的数组。

我们需要了解的下一个概念是如何避免空插槽。

避免空插槽
空插槽?这些是什么?

基本上,当您创建一个具有一定长度的数组而不指定每个索引的值时,您将拥有一个空索引,也称为一个空槽。

让我们看下面的例子:

const arrWithEmptySlots = [];
arrWithEmptySlots.length = 5;
arrWithEmptySlots[0] = "Jin";

//output ["Jin", empty × 4]
console.log(arrWithEmptySlots);

如何检查空插槽?
我们可以使用in运算符来检查数组是否具有键。此外,它返回一个boolean值,false为空时隙,但true用于与值槽,包括undefined值。

让我们看下面的例子:

const arrWithEmptySlots = [];
arrWithEmptySlots.length = 3;
arrWithEmptySlots[0] = undefined;
arrWithEmptySlots[1] = "Jin";

console.log(0 in arrWithEmptySlots);//true
console.log(1 in arrWithEmptySlots);//true
console.log(2 in arrWithEmptySlots);//false
console.log(3 in arrWithEmptySlots);//false

/**
 * output:
 * 0
 * 1
 */
for (let slot in arrWithEmptySlots) {
    
    
  console.log(slot);
}

这个空插槽与Array.from()方法有什么关系?

如果要生成一个初始化为一定长度的数组而没有空插槽,请Array.from()解决此问题。

const arrayWithEmptySlots_2 = [];
arrayWithEmptySlots_2.length = 5;

const results = Array.from(arrayWithEmptySlots_2);

//output: [undefined, undefined, undefined, undefined, undefined]
console.log(results);

在我们进入下一部分之前。

然后我们可以得出结论,Array.from()不仅Array从可迭代对象创建新实例。它还接受一个“类似数组的对象”,该对象将转换为真实数组,并帮助我们避免空插槽。

Array.of()方法
通常,每个人都知道Array构造函数是用来创建Array对象的。此外,Array.of()方法是Array构造方法的替代方法,本节将介绍原因。

句法
隐藏 复制代码
//syntax
//Array.of([]);
参量
[] –用于创建数组的元素
让我们看下面的一些例子:

创建一个新的Array构造函数并传递多个参数。

let cars = new Array("Toyota", "Mitsubishi", "Nissan", "Honda");

//output: 4
console.log(cars.length); 
//output: Toyota Mitsubishi Nissan Honda
console.log(...cars); 

let customers = new Array({
    
     name: "Jin" }, {
    
     name: "Vincent" }, {
    
     name: "Necesario" });

//output: 3
console.log(customers.length); 
//output: {name: "Jin"} {name: "Vincent"} {name: "Necesario"}
console.log(...customers); 

let luckyNumbers = new Array(23, 29, 32);

//output: 3
console.log(luckyNumbers.length);
//output: 23 29 32
console.log(...luckyNumbers);
创建一个新的Array构造函数并传递一个参数。并且,让我们看到故障。
隐藏   复制代码
let car = new Array("Toyota");
//still works.
console.log(car); 

let customer = new Array({
    
    name: "Jin"})
 //still works.
console.log(customer);

let luckyNumber = new Array(23);
//glitch
//output: 23
//23 in length????
console.log(luckyNumber.length); 

//another glitch
//output:  [empty × 23]
console.log(luckyNumber); 

您发现差异了吗?让我们以luckyNumber变量为例,与变量car和比较,结果不同customer。

请记住,当您传递一个带有数字值的参数时。它正在创建一个空数组,其length属性等于该数字,并根据length属性产生空插槽。

这是小故障吗?也许是或否。为了避免出现此问题,我们可以使用该Array.of()方法。

让我们看下面的例子:

let superLuckyNumber = Array.of(23);
console.log(superLuckyNumber); //output: [23]

因此,Array.of()引入了解决该问题的方法。

在评论部分让我知道您的想法。提前致谢。

copyWithin()方法
该copyWithin()方法用于将数组的值序列复制到数组中的其他位置。

句法

//syntax
//[].copyWithin(target, start, end);

target –将元素复制到的索引
start –可选,这是从其开始复制的索引位置
end –可选,这是实际结束复制元素的索引
如果起始索引为负,则将其视为数组长度加上起始索引([].length + start)。与结束索引([].length + end)相同。

let presidents1 = ["Donald Trump", "Barack Obama", "George Bush", "Bill Clinton"];
let presidents2 =  ["George H. W. Bush", "Ronald Reagan", "Jimmy Carter", "General Ford"];

//let's copy to index 0 from index 1
//let's replace Donald Trump with Barack Obama
//output: ["Barack Obama", "George Bush", "Bill Clinton", "Bill Clinton"]
console.log(presidents1.copyWithin(0, 1));

//let's copy to index 1 from index 2
//, let's replace Ronald Reagan with Jimmy Carter up to 3rd index. 
//Up to 2nd index only excluding 3rd index.
//output: ["George H. W. Bush", "Jimmy Carter", "Jimmy Carter", "General Ford"]
console.log(presidents2.copyWithin(1, 2, 3));

容易遵循是吗?让我们进入下一部分。

fill()方法
该fill方法实际上使用给定填充(全部或部分)从start索引到end索引的Array的所有元素value。此外,startandend索引是可选的;因此,如果未提供它们,则整个数组将由您传递的值填充。

句法
隐藏 复制代码
//syntax
//[].fill(value, start, end);
参量
value –填充数组的值
start –可选,是开始索引
end –可选,是结束索引
如果您已经看到Array构造函数的问题。同样,我们可以使用此方法为数组的所有空插槽设置值。

只要目标是初始化具有定义的长度且没有空插槽的数组,就可以执行此操作。

让我们看下面的例子:

let arryLenOf5 = new Array(5).fill(undefined);

//output: (5)[undefined, undefined, undefined, undefined, undefined]
console.log(arryLenOf5);

let arryLenOf3 = new Array(3).fill(0);

//output: (3) [0, 0, 0]
console.log(arryLenOf3);
//fills the entire array
console.log([29, 23, 5, 26, 16, 21].fill(29)); 
//output: [29, 29, 29, 29, 29, 29]

//fills the entire array starting at index 1
console.log([29, 23, 5, 26, 16, 21].fill(30, 1)); 
//output: [29, 30, 30, 30, 30, 30]

//fills the entire array starting at index 1 and ends at 5th position.
console.log([29, 23, 5, 26, 16, 21].fill(31, 2, 5)); 
//output: [29, 23, 31, 31, 31, 21]

如果起始索引为负,则将其视为数组长度加上起始索引([].length + start)。与结束索引([].length + end)相同。

//fills the entire array starting at index ([].length -2) = 4th index.
console.log([29, 23, 5, 26, 16, 21].fill(31, -2)); 
//output: [29, 23, 5, 26, 31, 31]

//fills the entire array starting at [1] index ends to ([].length -2) = 4th position.
console.log([29, 23, 5, 26, 16, 21].fill(31, 1, -2)); 
//output: [29, 31, 31, 31, 16, 21]

容易遵循是吗?让我们进入下一部分。

find()方法
在深入研究该find()方法之前,我们将先退一步。并回答:“它真正解决了什么?”

句法

//syntax
//[].find(callback(element,index,array), thisArg);

callback –对数组中的每个值执行的回调函数
thisArg–是可选的,在回调内部Object使用this
indexOf方法
通常,在中搜索值时首先想到Array的是indexOf() 方法的使用。

let nums = [9, 8, 7, 6, 5, 4, 3, 2, 1];

console.log(nums.indexOf(9)); //output: 0;
console.log((nums.indexOf(7) !== -1)); //output: true
console.log((nums.indexOf("9") == 0)); //output: false
console.log((nums.indexOf("Jin Vincent Necesario") !== -1)); //output: false

但是,有时程序员会忘记此方法需要严格的比较。我认为,这就是他们(程序员)使用该some()方法的原因。

some()方法
该方法通过为每个元素调用函数回调来起作用,直到一个返回atrue 或truthyvalue,最后停止。

好处是您可以控制值的比较,与indexOf() 方法不同。

let nums = [9, 8, 7, 6, 5, 4, 3, 2, 1];
console.log(nums.some((num) => num == "9")); //output: true
console.log(nums.some((num) => num === "9")); //output: false

现在,关于其缺点some()的方法是,你只能得到boolean价值true或者false,如果配合适当的值被发现,但不是实际的值相匹配的内容。

什么find()方法可以解决?
该find()方法解决了该问题。它的工作原理与some()方法相同,不同之处在于一旦回调函数返回其值,Array 则返回实际值。

因此,find()method返回一个数组元素。仅当满足所提供的条件时,该表达式才会传递给回调函数。否则,返回undefined。

let nums = [9, 8, 7, 6, 5, 4, 3, 2, 1];
console.log(nums.find((num) => num == "9")); //output: 9
console.log(nums.find((num) => num === "9"));//output: undefined

为什么没有另一个带有完整参数的示例?

let num = 5;
let nums = [9, 8, 7, 6, 5, 4, 3, 2, 1];
let result = nums.find(function (value, index, array) {
    
    

  //just shows the values to the console window.
  console.log(`The num[${
    
    index}] is equal to ${
    
    value} ${
    
    this}`);

  return value === parseInt(this);
}, num);

console.log(result); //output: 5

findIndex()方法
这几乎类似于该find()方法。但是,它返回数组元素的索引,而不是元素本身。

句法

//syntax
//[].findIndex(callback(element,index,array), thisArg);

参量
callback–对数组中的每个值执行直到函数返回的回调函数true。否则,undefined表示未找到该元素。
thisArg –是可选的
回到该indexOf()方法,我们已经看到对其匹配逻辑没有控制权。这样,findIndex()节省了一天。

let num = 5;
let nums = [9, 8, 7, 6, 5, 4, 3, 2, 1];
let result = nums.findIndex(function (value, index, array) {
    
    

  //just shows the values to the console window.
  console.log(`The num[${
    
    index}] is equal to ${
    
    value} ${
    
    this}`);

  return value === parseInt(this);
}, num);

console.log(result); //output: 4

现在,我们对find() 方法以及find() 和 findIndex()的相似性 有了很好的 了解。

让我们再举一个例子,一个定制的搜索。

const houses = [
  {
    
     length: 22,  width: 288,  measurement: 'ft' },
  {
    
     length: 182, width: 532,  measurement: 'ft' },
  {
    
     length: 12,  width: 152,  measurement: 'ft' },
  {
    
     length: 20,  width: 30,   measurement: 'ft' },
  {
    
     length: 12,  width: 152,  measurement: 'ft' }];

let indexResult = houses.findIndex((house) => (house.length * house.width) === 600);

console.log(indexResult); //output: 3

什么时候使用find()和findIndex()方法?
不要像对待findIndex(方法那样对待)方法indexOf() ,因为我们有some()方法可以返回所需的布尔值。
不要使用findIndex()method获取匹配的值,因为这就是该find()方法的目的。
indexOf()如果需要严格匹配,请使用方法。
findIndex()如果需要更自定义的匹配项的索引,请使用。
entry()方法
此方法返回一个可迭代的对象。此外,实际返回的对象是 Array Iterator ,其中包含数组每个索引的键/值对。

句法

//syntax  
//[].entries();    
let fruits = ['mango', 'apple', 'dragon fruit'];  
//output: returns Array Iterator {}  
console.log(fruits.entries());  
/* 
Let us show the [key, value] pair 
*/  
let fruitEntries = fruits.entries();  
/* 
Output: 
[0, "mango"] 
[1, "apple"] 
[2, "dragon fruit"] 
*/  
for (let current of fruitEntries){
    
      
console.log(current);  
}  
/*let us show the index and element of the fruits array 
Output: 
0 "mango" 
1 "apple" 
2 "dragon fruit" 
*/  
for(let [index, element] of fruits.entries()){
    
      
console.log(index, element);  
}      

keys()方法
该方法类似于该entries()方法。但是,返回的对象包含数组中每个索引的键。

句法

//syntax  
//[].keys();     
let fruits = ['mango', 'apple', 'dragon fruit'];  
//output: Array Iterator {}  
console.log(fruits.keys());  
let fruitKeys = fruits.keys();  
//output: 0 1 2  
console.log(...fruitKeys);    

values()方法
此方法的行为类似于[].keys()和[].entries()。但是,不同的是,此方法返回数组中每个键的值。

句法

//syntax   
[].values();    
let fruits = ['mango', 'apple', 'dragon fruit'];  
//output: Array Iterator {}  
console.log(fruits.values());  
let fruitKeys = fruits.values();  
//output: "mango" "apple" "dragon fruit"  
console.log(...fruitKeys); 

猜你喜欢

转载自blog.csdn.net/u014249305/article/details/110731256