JavaScript Array(数组) 对象

JavaScript Array(数组) 对象

一、什么是数组?

数组对象是使用单独的变量名来存储一系列的值

二、创建数组的三种方法:

1、常规方式:

var myCars=new Array();
myCars[0]="Saab";     
myCars[1]="Volvo";
myCars[2]="BMW";

2、简洁方式:

var myCars=new Array("Saab","Volvo","BMW");

3、数组直接量:或者叫字面量写法

var myCars=["Saab","Volvo","BMW"]; 

在一个数组中可以有不同的对象,包括对象元素、函数、数组等

三、数组属性

1、constructor返回创建数组对象的原型函数Array。

var fruits = ["Banana", "Orange", "Apple", "Mango"];
// 返回fruits数组对象原型创建的函数:
fruits.constructor; --> function Array() { [native code] }
Array.constructor; --> function Function() {[native code]}
console.log(fruits.constructor===Array) // true

2、length设置或返回数组元素的个数,表示数组的长度。

var fruits = ["Banana", "Orange", "Apple", "Mango"];
返回数组的数目:
fruits.length;
结果输出:4

3、prototype允许你向数组对象添加属性或方法。(构造器属性)
原型添加api实现:

// 一个新的数组的方法,将数组值转为大写:
Array.prototype.myUcase=function() {
    for (i=0;i<this.length;i++) {
this[i]=this[i].toUpperCase();
    }
}

// 创建一个数组,然后调用 myUcase 方法:
var fruits=["Banana","Orange","Apple","Mango"];
fruits.myUcase();
console.log(fruits) // ["BANANA", "ORANGE", "APPLE", "MANGO"]
// fruits 数组现在的值为:BANANA,ORANGE,APPLE,MANGO

定义和用法
prototype 属性使您有能力向对象添加属性和方法。
当构建一个属性,所有的数组将被设置属性,它是默认值。
在构建一个方法时,所有的数组都可以使用该方法。
注意: Array.prototype 单独不能引用数组, Array() 对象可以。
注意: 在JavaScript对象中,prototype是一个全局属性。

四、数组方法(api)

三个静态api
Array.from()
Array.isArray()
Array.of()
三十一个原型api
Array.prototype.concat()
Array.prototype.copyWithin()
Array.prototype.entries()
Array.prototype.every()
Array.prototype.fill()
Array.prototype.filter()
Array.prototype.find()
Array.prototype.findIndex()
Array.prototype.flat()
Array.prototype.flatMap()
Array.prototype.forEach()
Array.prototype.includes()
Array.prototype.indexOf()
Array.prototype.join()
Array.prototype.keys()
Array.prototype.lastIndexOf()
Array.prototype.map()
Array.prototype.pop()
Array.prototype.push()
Array.prototype.reduce()
Array.prototype.reduceRight()
Array.prototype.reverse()
Array.prototype.shift()
Array.prototype.slice()
Array.prototype.some()
Array.prototype.sort()
Array.prototype.splice()
Array.prototype.toLocaleString()
Array.prototype.toString()
Array.prototype.unshift()
Array.prototype.values()
1、Array.from() 方法从一个类似数组或可迭代对象创建一个新的,浅拷贝的数组实例。
语法:Array.from(arrayLike[, mapFn[, thisArg]])

console.log(Array.from('foo'));
// expected output: Array ["f", "o", "o"]

console.log(Array.from([1, 2, 3], x => x + x));
// expected output: Array [2, 4, 6]

2、Array.isArray() 用于确定传递的值是否是一个 Array。
语法:Array.isArray(obj)

Array.isArray([1, 2, 3]);  
// true
Array.isArray({foo: 123}); 
// false
Array.isArray("foobar");   
// false
Array.isArray(undefined);  
// false

3、Array.of() 方法创建一个具有可变数量参数的新数组实例,而不考虑参数的数量或类型。
语法:Array.of(element0[, element1[, ...[, elementN]]])
Array.of() 和 Array 构造函数之间的区别在于处理整数参数:Array.of(7) 创建一个具有单个元素 7 的数组,而 Array(7) 创建一个长度为7的空数组(注意:这是指一个有7个空位(empty)的数组,而不是由7个undefined组成的数组)。

Array.of(7);       // [7] 
Array.of(1, 2, 3); // [1, 2, 3]

Array(7);          // [ , , , , , , ]
Array(1, 2, 3);    // [1, 2, 3]

4、 concat() 方法用于合并两个或多个数组。此方法不会更改现有数组,而是返回一个新数组。
语法:var new_array = old_array.concat(value1[, value2[, ...[, valueN]]])

const array1 = ['a', 'b', 'c'];
const array2 = ['d', 'e', 'f'];
const array3 = array1.concat(array2);

console.log(array3);
// expected output: Array ["a", "b", "c", "d", "e", "f"]

5、copyWithin() 方法浅复制数组的一部分到同一数组中的另一个位置,并返回它,不会改变原数组的长度。
语法:arr.copyWithin(target[, start[, end]])

const array1 = ['a', 'b', 'c', 'd', 'e'];

// copy to index 0 the element at index 3
console.log(array1.copyWithin(0, 3, 4));
// expected output: Array ["d", "b", "c", "d", "e"]

// copy to index 1 all elements from index 3 to the end
console.log(array1.copyWithin(1, 3));
// expected output: Array ["d", "d", "e", "d", "e"]

6、entries() 方法返回一个新的Array Iterator对象,该对象包含数组中每个索引的键/值对。
语法:arr.entries()

const array1 = ['a', 'b', 'c'];

const iterator1 = array1.entries();

console.log(iterator1.next().value);
// expected output: Array [0, "a"]

console.log(iterator1.next().value);
// expected output: Array [1, "b"]

7、every() 方法测试一个数组内的所有元素是否都能通过某个指定函数的测试。它返回一个布尔值。
注意:若收到一个空数组,此方法在一切情况下都会返回 true。
语法:arr.every(callback[, thisArg])

const isBelowThreshold = (currentValue) => currentValue < 40;

const array1 = [1, 30, 39, 29, 10, 13];

console.log(array1.every(isBelowThreshold));
// expected output: true

8、fill() 方法用一个固定值填充一个数组中从起始索引到终止索引内的全部元素。不包括终止索引。
语法:arr.fill(value[, start[, end]])

const array1 = [1, 2, 3, 4];

// fill with 0 from position 2 until position 4
console.log(array1.fill(0, 2, 4));
// expected output: [1, 2, 0, 0]

// fill with 5 from position 1
console.log(array1.fill(5, 1));
// expected output: [1, 5, 5, 5]

console.log(array1.fill(6));
// expected output: [6, 6, 6, 6]

9、filter() 方法创建一个新数组, 其包含通过所提供函数实现的测试的所有元素。
语法:var newArray = arr.filter(callback(element[, index[, array]])[, thisArg])

const words = ['spray', 'limit', 'elite', 'exuberant', 'destruction', 'present'];

const result = words.filter(word => word.length > 6);

console.log(result);
// expected output: Array ["exuberant", "destruction", "present"]

10、find() 方法返回数组中满足提供的测试函数的第一个元素的值。否则返回 undefined。
语法:arr.find(callback[, thisArg])

const array1 = [5, 12, 8, 130, 44];

const found = array1.find(element => element > 10);

console.log(found);
// expected output: 12

11、findIndex()方法返回数组中满足提供的测试函数的第一个元素的索引。否则返回-1。
语法:arr.findIndex(callback[, thisArg])

const array1 = [5, 12, 8, 130, 44];

const isLargeNumber = (element) => element > 13;

console.log(array1.findIndex(isLargeNumber));
// expected output: 3

12、flat() 方法会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。
语法:var newArray = arr.flat([depth])


var arr1 = [1, 2, [3, 4]];
arr1.flat(); 
// [1, 2, 3, 4]

var arr2 = [1, 2, [3, 4, [5, 6]]];
arr2.flat();
// [1, 2, 3, 4, [5, 6]]

var arr3 = [1, 2, [3, 4, [5, 6]]];
arr3.flat(2);
// [1, 2, 3, 4, 5, 6]

//使用 Infinity,可展开任意深度的嵌套数组
var arr4 = [1, 2, [3, 4, [5, 6, [7, 8, [9, 10]]]]];
arr4.flat(Infinity);
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

var arr4 = [1, 2, , 4, 5];
arr4.flat();
// [1, 2, 4, 5]

13、flatMap() 方法首先使用映射函数映射每个元素,然后将结果压缩成一个新数组。它与 map 连着深度值为1的 flat 几乎相同,但 flatMap 通常在合并成一种方法的效率稍微高一些。
语法:var new_array = arr.flatMap(function callback(currentValue[, index[, array]]) {
// return element for new_array
}[, thisArg])

var arr1 = [1, 2, 3, 4];

arr1.map(x => [x * 2]); 
// [[2], [4], [6], [8]]

arr1.flatMap(x => [x * 2]);
// [2, 4, 6, 8]

// only one level is flattened
arr1.flatMap(x => [[x * 2]]);
// [[2], [4], [6], [8]]

虽然上面的代码使用 map 和 flatMap 好像都可以,但这只能展示如何使用 flatMap。
所以,为了更好的展示 flatMap 的作用,下面我们将包含几句话的数组拆分成单个汉字组成的新数组。

let arr1 = ["it's Sunny in", "", "California"];

arr1.map(x => x.split(" "));
// [["it's","Sunny","in"],[""],["California"]]

arr1.flatMap(x => x.split(" "));
// ["it's","Sunny","in", "", "California"]

注意,输出列表长度可以不同于输入列表长度。

14、forEach() 方法对数组的每个元素执行一次给定的函数。
语法:arr.forEach(callback(currentValue [, index [, array]])[, thisArg])

const array1 = ['a', 'b', 'c'];

array1.forEach(element => console.log(element));

// expected output: "a"
// expected output: "b"
// expected output: "c"

15、includes() 方法用来判断一个数组是否包含一个指定的值,根据情况,如果包含则返回 true,否则返回false。
语法:arr.includes(valueToFind[, fromIndex])

const array1 = [1, 2, 3];

console.log(array1.includes(2));
// expected output: true

const pets = ['cat', 'dog', 'bat'];

console.log(pets.includes('cat'));
// expected output: true

console.log(pets.includes('at'));
// expected output: false

16、indexOf()方法返回在数组中可以找到一个给定元素的第一个索引,如果不存在,则返回-1。
语法:arr.indexOf(searchElement[, fromIndex])

const beasts = ['ant', 'bison', 'camel', 'duck', 'bison'];

console.log(beasts.indexOf('bison'));
// expected output: 1

// start from index 2
console.log(beasts.indexOf('bison', 2));
// expected output: 4

console.log(beasts.indexOf('giraffe'));
// expected output: -1

17、join() 方法将一个数组(或一个类数组对象)的所有元素连接成一个字符串并返回这个字符串。如果数组只有一个项目,那么将返回该项目而不使用分隔符。
语法:arr.join([separator])

const elements = ['Fire', 'Air', 'Water'];

console.log(elements.join());
// expected output: "Fire,Air,Water"

console.log(elements.join(''));
// expected output: "FireAirWater"

console.log(elements.join('-'));
// expected output: "Fire-Air-Water"

18、keys() 方法返回一个包含数组中每个索引键的Array Iterator对象。
语法:arr.keys()

const array1 = ['a', 'b', 'c'];
const iterator = array1.keys();

for (const key of iterator) {
  console.log(key);
}

// expected output: 0
// expected output: 1
// expected output: 2

19、lastIndexOf() 方法返回指定元素(也即有效的 JavaScript 值或变量)在数组中的最后一个的索引,如果不存在则返回 -1。从数组的后面向前查找,从 fromIndex 处开始。
语法:arr.lastIndexOf(searchElement[, fromIndex])

const animals = ['Dodo', 'Tiger', 'Penguin', 'Dodo'];

console.log(animals.lastIndexOf('Dodo'));
// expected output: 3

console.log(animals.lastIndexOf('Tiger'));
// expected output: 1

20、map() 方法创建一个新数组,其结果是该数组中的每个元素都调用一次提供的函数后的返回值。
语法:var new_array = arr.map(function callback(currentValue[, index[, array]]) {
// Return element for new_array
}[, thisArg])

const array1 = [1, 4, 9, 16];

// pass a function to map
const map1 = array1.map(x => x * 2);

console.log(map1);
// expected output: Array [2, 8, 18, 32]

21、pop()方法从数组中删除最后一个元素,并返回该元素的值。此方法更改数组的长度。
语法:arr.pop()

const plants = ['broccoli', 'cauliflower', 'cabbage', 'kale', 'tomato'];

console.log(plants.pop());
// expected output: "tomato"

console.log(plants);
// expected output: Array ["broccoli", "cauliflower", "cabbage", "kale"]

plants.pop();

console.log(plants);
// expected output: Array ["broccoli", "cauliflower", "cabbage"]

22、push() 方法将一个或多个元素添加到数组的末尾,并返回该数组的新长度。
语法:arr.push(element1, ..., elementN)

const animals = ['pigs', 'goats', 'sheep'];

const count = animals.push('cows');
console.log(count);
// expected output: 4
console.log(animals);
// expected output: Array ["pigs", "goats", "sheep", "cows"]

animals.push('chickens', 'cats', 'dogs');
console.log(animals);
// expected output: Array ["pigs", "goats", "sheep", "cows", "chickens", "cats", "dogs"]

23、reduce() 方法对数组中的每个元素执行一个由您提供的reducer函数(升序执行),将其结果汇总为单个返回值。
语法:arr.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue])

reducer 函数接收4个参数:
Accumulator (acc) (累计器)
Current Value (cur) (当前值)
Current Index (idx) (当前索引)
Source Array (src) (源数组)
您的 reducer 函数的返回值分配给累计器,该返回值在数组的每个迭代中被记住,并最后成为最终的单个结果值。

const array1 = [1, 2, 3, 4];
const reducer = (accumulator, currentValue) => accumulator + currentValue;

// 1 + 2 + 3 + 4
console.log(array1.reduce(reducer));
// expected output: 10

// 5 + 1 + 2 + 3 + 4
console.log(array1.reduce(reducer, 5));
// expected output: 15

reduce() 数组简算缩减 rightReduce()

var sum = array.reduce(function (prev, next, currentIndex, arr) {
    // console.log(arr);
    // console.log(currentIndex);
    console.log(prev + "----" + next);
    return prev + next;
}, 0); // 当第二个参数不传值是 prev 第一次默认是数组第一个元素 

/*  0----10
    10----23
    33----21
    54----34
    88----44
    132----88
    220 
  */
// 传入第二个参数时 prev第一次就是该参数
console.log(sum);

/*[10,23,21,34,44,88]
    10----23
    33----21
    54----34
    88----44
    132----88

  第一次 prev指向数组第一个元素
        next指向数组第二个元素
  后面 prev表示上一次函数的返回值,next每次指向下一个元素

  prev 10 next 23 return 33
  prev 33 next 21 return 33+21
  prev 33+21 next 34 return 33+21+34
  prev 33+21+34 next 44 return 33+21+34+44
  prev 33+21+34+44 next 88 return 33+21+34+44+88
*/

24、reduceRight() 方法接受一个函数作为累加器(accumulator)和数组的每个值(从右到左)将其减少为单个值。
语法:arr.reduceRight(callback(accumulator, currentValue[, index[, array]])[, initialValue])

const array1 = [[0, 1], [2, 3], [4, 5]].reduceRight(
  (accumulator, currentValue) => accumulator.concat(currentValue)
);

console.log(array1);
// expected output: Array [4, 5, 2, 3, 0, 1]

25、reverse() 方法将数组中元素的位置颠倒,并返回该数组。数组的第一个元素会变成最后一个,数组的最后一个元素变成第一个。该方法会改变原数组。
语法:arr.reverse()

const array1 = ['one', 'two', 'three'];
console.log('array1:', array1);
// expected output: "array1:" Array ["one", "two", "three"]

const reversed = array1.reverse();
console.log('reversed:', reversed);
// expected output: "reversed:" Array ["three", "two", "one"]

// Careful: reverse is destructive -- it changes the original array.
console.log('array1:', array1);
// expected output: "array1:" Array ["three", "two", "one"]

26、shift() 方法从数组中删除第一个元素,并返回该元素的值。此方法更改数组的长度。
语法:arr.shift()

const array1 = [1, 2, 3];

const firstElement = array1.shift();

console.log(array1);
// expected output: Array [2, 3]

console.log(firstElement);
// expected output: 1

27、slice() 方法返回一个新的数组对象,这一对象是一个由 begin 和 end 决定的原数组的浅拷贝(包括 begin,不包括end)。原始数组不会被改变。
语法:arr.slice([begin[, end]])

const animals = ['ant', 'bison', 'camel', 'duck', 'elephant'];

console.log(animals.slice(2));
// expected output: Array ["camel", "duck", "elephant"]

console.log(animals.slice(2, 4));
// expected output: Array ["camel", "duck"]

console.log(animals.slice(1, 5));
// expected output: Array ["bison", "camel", "duck", "elephant"]

28、some() 方法测试数组中是不是至少有1个元素通过了被提供的函数测试。它返回的是一个Boolean类型的值。
注意:如果用一个空数组进行测试,在任何情况下它返回的都是false。
语法:arr.some(callback(element[, index[, array]])[, thisArg])

const array = [1, 2, 3, 4, 5];

// checks whether an element is even
const even = (element) => element % 2 === 0;

console.log(array.some(even));
// expected output: true

29、sort() 方法用原地算法对数组的元素进行排序,并返回数组。默认排序顺序是在将元素转换为字符串,然后比较它们的UTF-16代码单元值序列时构建的

由于它取决于具体实现,因此无法保证排序的时间和空间复杂性。
语法:arr.sort([compareFunction])

const months = ['March', 'Jan', 'Feb', 'Dec'];
months.sort();
console.log(months);
// expected output: Array ["Dec", "Feb", "Jan", "March"]

const array1 = [1, 30, 4, 21, 100000];
array1.sort();
console.log(array1);
// expected output: Array [1, 100000, 21, 30, 4]

30、splice() 方法通过删除或替换现有元素或者原地添加新的元素来修改数组,并以数组形式返回被修改的内容。此方法会改变原数组。
语法:array.splice(start[, deleteCount[, item1[, item2[, ...]]]])

function mySplice() {
var arr = [1, 2, 3, 4, 5];
// 删除  第一个参数是从下标为几的元素开始删除,第二个参数为删除几个元素
// var res = arr.splice(1, 2); // 从索引为1开始删除两个
// console.log(arr); // [1,4,5]
// console.log(res); // [2,3]
// 添加  第二个参数设为0,添加第三个参数,表示再插入一个数在下标为2的数前面,返回值是空数组
// var res = arr.splice(2, 0, 6); //当第二个参数为0时,在索引为2的前面添加6
// console.log(arr); //[1,2,6,3,4,5]
// console.log(res); //[]
// 替换  先删再加,表示替换,返回值是被删除的元素组成的数组
var res = arr.splice(1, 2, 100, 200, 300, 400, 500); // 从索引为1开始用后面所有数据替换两个
console.log(arr); //[1,100,200,300,400,500,4,5]
console.log(res);//[2,3]
}
mySplice();
------------------------------------------------
const months = ['Jan', 'March', 'April', 'June'];
months.splice(1, 0, 'Feb');
// inserts at index 1
console.log(months);
// expected output: Array ["Jan", "Feb", "March", "April", "June"]

months.splice(4, 1, 'May');
// replaces 1 element at index 4
console.log(months);
// expected output: Array ["Jan", "Feb", "March", "April", "May"]

31、toLocaleString() 返回一个字符串表示数组中的元素。数组中的元素将使用各自的 toLocaleString 方法转成字符串,这些字符串将使用一个特定语言环境的字符串(例如一个逗号 ",")隔开。
语法:arr.toLocaleString([locales[,options]]);

const array1 = [1, 'a', new Date('21 Dec 1997 14:12:00 UTC')];
const localeString = array1.toLocaleString('en', { timeZone: 'UTC' });

console.log(localeString);
// expected output: "1,a,12/21/1997, 2:12:00 PM",
// This assumes "en" locale and UTC timezone - your results may vary

32、toString() 返回一个字符串,表示指定的数组及其元素。
语法:arr.toString()

const array1 = [1, 2, 'a', '1a'];

console.log(array1.toString());
// expected output: "1,2,a,1a"

33、unshift() 方法将一个或多个元素添加到数组的开头,并返回该数组的新长度(该方法修改原有数组)。
语法:arr.unshift(element1, ..., elementN)

const array1 = [1, 2, 3];

console.log(array1.unshift(4, 5));
// expected output: 5

console.log(array1);
// expected output: Array [4, 5, 1, 2, 3]

34、values() 方法返回一个新的 Array Iterator 对象,该对象包含数组每个索引的值
语法:arr.values()

const array1 = ['a', 'b', 'c'];
const iterator = array1.values();

for (const value of iterator) {
  console.log(value);
}

// expected output: "a"
// expected output: "b"
// expected output: "c"

35、valueOf() 返回数组对象的原始值。
语法:arr.valueOf(arr)

var arr = [1, 2, 3];
console.log(arr.valueOf(arr));
expected output: Array [1, 2, 3]

五、手写实现部分api

1、push()

var arr = [1, 2, 3];
Array.prototype.myPush = function() {
    for (var i = 0; i < arguments.length; i++) {
//arguments代表实参的集合
//this 指向的是arr数组
this[this.length] = arguments[i];
    }
//由于push 返回值 是一个数组的长度 所以 我们来个return;
    return this.length;
};

arr.myPush(4,5,6);
console.log(arr); // [1, 2, 3, 4, 5, 6]

2、Every
every() 方法用于检测数组所有元素是否都符合指定条件(通过函数提供)。
every() 方法使用指定函数检测数组中的所有元素:
如果数组中检测到有一个元素不满足,则整个表达式返回 false ,且剩余的元素不会再进行检测。
如果所有元素都满足条件,则返回 true。
注意: every() 对空数组检测 返回 true。
注意: every() 不会改变原始数组。
语法:array.every(function(currentValue,index,arr), thisValue)

Array.prototype._every = function (fn, thisValue) {
    let arr = thisValue || this // thisValue 有值 就以thisValue 为准
    if (typeof fn !== 'function') {
      throw new TypeError(fn + ' is not a function');
    }
    // 空数组 返回 true
    if (!arr.length) {
      return true
    }
    for (let i = 0; i < arr.length; i++) {
      if (!fn.call(this, arr[i], i, arr)) {
        return false
      }
    }
    return true
}
 
function checkAdult(item) {
  return item >= 11
}
 
let arr = [32, 33, 16, 40]
let result = arr._every(checkAdult)
console.log(result) // true

3、Filter
filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。
注意: filter() 不会对空数组进行检测。
注意: filter() 不会改变原始数组。
语法:array.filter(function(currentValue,index,arr), thisValue)

Array.prototype._filter = function (fn, thisValue) {
    let arr = thisValue || this
    let result = []
    if (typeof fn !== 'function') {
      throw new TypeError(fn + ' is not a function');
    }
    if (!arr.length) { // 空数组不处理 直接返回空数组
        return []
    }
    for (let i = 0; i < arr.length; i++) {
      if(fn.call(arr, arr[i], i, arr)) {
        result.push(arr[i])
      }
    }
    return result
}
 
let arr = [4, 9, 16, 25];
let result = arr._filter((item) => {
    return item > 10
})
console.log(result) // [16, 25]

4、Find
find() 方法返回通过测试(函数内判断)的数组的第一个元素的值。
find() 方法为数组中的每个元素都调用一次函数执行:
当数组中的元素在测试条件时返回 true 时, find() 返回符合条件的元素,之后的值不会再调用执行函数。
如果没有符合条件的元素返回 undefined
注意: find() 对于空数组,函数是不会执行的。
注意: find() 并没有改变数组的原始值。
语法:array.find(function(currentValue, index, arr),thisValue)

Array.prototype._find = function (fn, thisValue) {
  let arr = thisValue || this
    if (typeof fn !== 'function') {
    throw new TypeError(fn + ' is not a function');
  }
  if (!this.length) { // 空数组返回 undefined
    return undefined
  }
  for (let i = 0; i < arr.length; i++) {
    let result = fn.call(arr, arr[i], i, arr)
    if (result) {
      return arr[i]
    }
  }
  return undefined
}
 
let arr = [3, 10, 18, 20]
function checkAdult(age) {
  return age > 11
}
let result = arr._find(checkAdult)
console.log(result) // 18

5、IndexOf
indexOf() 方法可返回数组中某个指定的元素位置。
该方法将从头到尾地检索数组,看它是否含有对应的元素。开始检索的位置在数组 start 处或数组的开头(没有指定 start 参数时)。如果找到一个 item,则返回 item 的第一次出现的位置。开始位置的索引为 0。
如果在数组中没找到指定元素则返回 -1。
语法:array.indexOf(item,start)

Array.prototype._indexOf = function (item, start = 0) {
  let arr = this
  for (let i = start; i < arr.length; i++) {
    if (item === arr[i]) {
      return i
    }
  }
  return -1
}
 
let arr = ["Banana","Orange","Apple","Mango","Banana","Orange","Apple"];
let result = arr._indexOf("Apple", 4)
console.log(result) // 6

6、ForEach
forEach() 方法用于调用数组的每个元素,并将元素传递给回调函数。
注意: forEach() 对于空数组是不会执行回调函数的。
语法:array.forEach(function(currentValue, index, arr), thisValue)

Array.prototype._forEach = function (fn, thisValue) {
    let arr = thisValue || this
    if (typeof fn !== 'function') {
      throw new TypeError(fn + ' is not a function');
    }
    for (let i = 0; i < arr.length; i++) {
      fn.call(arr, arr[i], i, arr);
    }
}
 
let arr = [4, 9, 16, 25];
arr._forEach((item, i, arr) => {
    console.log('item:' + item + '  i: ' + i)

7、From
from() 方法用于通过拥有 length 属性的对象或可迭代的对象来返回一个数组。
如果对象是数组返回 true,否则返回 false。Array.from(object, mapFunction, thisValue)

Array.prototype._from = function (object, mapFunction, thisValue) {
    let obj = thisValue || this
    let result = []
    // 没有length属性 或者 length 为0的 直接返回空数组
    if (!object.length) {
        return result
    }
    if (typeof object === 'string') {
        result = object.split('')
    } else {
        object.forEach(item => result.push(item))
    }
    if (typeof mapFunction !== 'function') {
      throw new TypeError(mapFunction + ' is not a function');
    }
    return result.map(mapFunction, thisValue)
}

let r1 = Array.prototype._from([1, 2, 3], x => x * 10)
console.log(r1) // [10, 20, 30, 40]
let r2 = Array.prototype._from('1234', x => x * 10)
console.log(r2) // [10, 20, 30]

8、Includes
includes() 方法用来判断一个数组是否包含一个指定的值,如果是返回 true,否则false。
语法:
arr.includes(searchElement)
arr.includes(searchElement, fromIndex)

Array.prototype._includes = function (searchElement, fromIndex = 0) {
  let arr = this
  if (fromIndex >= arr.length || !arr.length){
    return false
  }
  for (let i = fromIndex; i < arr.length; i++) {
    if (arr[i] === searchElement) {
      return true
    }
  }
  return false
}
 
let arr = ['a', 'b', 'c', 'd']
 
let result = arr._includes('b')
console.log(result) // true

9、isArray
isArray() 方法用于判断一个对象是否为数组。
如果对象是数组返回 true,否则返回 false。

Array.prototype._isArray = function (item) {
  // 只是判断数组用这个就够了
  // 判断数据类型最全面,最准确的方式是用 Object.prototype.toString.call(1)
  if(item.__proto__.constructor === Array) {
    return true
  } else {
    return false
  }
}
 
let arr = [1, 2, 3, 4]
console.log(Array.prototype._isArray(arr))  // true

10、Map
map() 方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。
map() 方法按照原始数组元素顺序依次处理元素。
注意: map() 不会对空数组进行检测。
注意: map() 不会改变原始数组。
array.map(function(currentValue,index,arr), thisValue)

Array.prototype._map = function (fn, thisValue) {
  let arr = thisValue || this
  let result = []
    if (typeof fn !== 'function') {
    throw new TypeError(fn + ' is not a function');
  }
  for (let i = 0; i < arr.length; i++) {
    let r = fn.call(arr, arr[i], i, arr)
    result.push(r)
  }
  return result
}
 
let arr = [4, 9, 16, 25];
let result = arr._map((item) => {
    return item * 2
})
 
console.log(result) //[8, 18, 32, 50]
console.log(arr) //[4, 9, 16, 25]

11、Reduce
reduce() 方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。
reduce() 可以作为一个高阶函数,用于函数的 compose。
注意: reduce() 对于空数组是不会执行回调函数的。
语法:array.reduce(function(total, currentValue, currentIndex, arr), initialValue)

Array.prototype._reduce = function (fn, initialValue) {
  let arr = this
    if (typeof fn !== 'function') {
    throw new TypeError(fn + ' is not a function');
  }
  if (!arr.length) {
    throw new TypeError('数组不能为空');
  }
  let result = initialValue || 0
  for (let i = 0; i < arr.length; i++) {
    result = fn.call(arr, result, arr[i], i, arr)
  }
  return result
}
 
let arr = [1, 2, 3, 4];
function getSum(total, currentValue, currentIndex, arr) {
  return total + currentValue
}
let result = arr._reduce(getSum, 2)
console.log(result) // 12

12、Slice

Array.prototype._slice = function (start, end) {
    let result = []
  for (let i = start; i < start + end; i++){
    result.push(this[i])
  }
  return result
}
 
let arr = ["Banana", "Orange", "Lemon", "Apple", "Mango"]
let result = arr._slice(1, 3)
 
console.log(result) // ["Orange", "Lemon", "Apple"]
console.log(arr) // ["Banana", "Orange", "Lemon", "Apple", "Mango"]

13、Splice

Array.prototype._splice = function (index, howmany = 0) {
  let arr = this
  let left = arr.slice(0, index) // 截取左边的数组
  let right = arr.slice(index + howmany, arr.length) // 截取右边的数组
  let subArr = Array.prototype.slice.call(arguments, 2) // 截取参数里面需要添加的数组
  let result = []
  // 合并数组
  result = [...left, ...subArr, ...right]
  // 这里改变 this, 就是改变原数组
  for (let i = 0; i < result.length; i++) {
    this[i] = result[i]
  }
  // 返回删除的数据
  return this.slice(index, index + howmany)
}
 
let arr = ["Banana", "Orange", "Lemon", "Apple", "Mango"]
let result = arr._splice(2, 1, "sss", "xxx")
console.log(result) // ["sss"]
console.log(arr) // ["Banana", "Orange", "sss", "xxx", "Apple", "Mango"]

14、Sort

var arr = [5, 10, 7, 15, 8, 20];
Array.prototype.mySort = function (array, fn) {
    for (var i = 0; i < array.length - 1; i++) {
        var isSorted = true;
        for (var j = 0; j < array.length - 1 - i; j++) {
            if (fn(array[j], array[j + 1]) > 0) {
                var temp = array[j];
                array[j] = array[j + 1];
                array[j + 1] = temp;
                isSorted = false;
            }
        }
        if (isSorted) {
            break;
        }
    }
}
arr.mySort(this, function (a, b) {
    return b - a;
});
console.log(arr);
原文地址:https://www.cnblogs.com/kaizhadiyishuai/p/13953651.html