| 返回新数组,不改变原数组 | 返回新数组,改变原数组(加减排序操作) | 其他 |
| joinconcatsliceeverysomefilter | poppushshiftunshiftreversesort (默认排序顺序为按字母升序,ascii码)splice | toString()和toLocaleString()indexOf()和lastIndexOf()fromofcopyWithinfind()和findIndex()fillentries()、keys()、values() ['a','b'].keys()includes |
map,forEach方法注意:
当数组元素是基本数据类型时,方法不会改变原数组;当数组元素是引用类型时,方法会改变原数组。 events.jianshu.io/p/d709fe2be…
原因是因为基本类型传值是复制,引用类型传值是引用
map(不会对空数组进行检测)
forEach(对于空数组是不会调用回调函数的, 不返回新数组)
reduce和reduceRight
let a = [1, 5, 6, 7, 8, 1, 5];
let b = a.reduce(function (pre, cur) {
pre.indexOf(cur) === -1 && pre.push(cur);
return pre;
}, []);
let c = a.reduce(function (pre, cur) {
return pre + cur;
}, 0);
数组去重: juejin.im/post/5c7b8b…
| 好用的(完美解决) | 一般的 |
| ES6 的 Set 对象Map 的 has 方法includesreducelodash 中的 _.uniq | indexOf 没处理 NaNsort 没处理 NaN双层 for 循环 + splice 没处理 NaN原始去重 没处理 NaNfilter + hasOwnProperty 存在问题对象的属性 把 {} 给处理了 |
// Map去重
let arr = [1, 2, 3, 1, 2, 3, "a", "a", "b"];
function arrayNoRepeat(arr) {
let map = new Map();
let result = new Array(); // 数组用于返回结果
for (let i = 0; i < arr.length; i++) {
if (!map.has(arr[i])) {
// 判断 map 中是否已有该 key 值
map.set(arr[i], true);
result.push(arr[i]);
}
}
return result;
}
console.log(arrayNoRepeat(arr));
//[1, 2, 3, "a", "b"]
// Set去重
const set = new Set([1, 2, 3, 4, 4]);
[...set];
// [1, 2, 3, 4]
所谓类似数组的对象,本质特征只有一点,即必须有length属性。因此,任何有length属性的对象,都可以通过Array.from方法转为数组,而此时扩展运算符就无法转换。
对Array.apply(null, { length: 10 })的解释
ES5开始apply函数的第二个参数除了可以是数组外,还可以是类数组对象(即包含length属性,且length属性值是个数字的对象)。对象{length: 2}就是一个类数组对象,因为没有初始化下标0,1的值,所以获取0,1下标的值得到的都是undefined。
// 1 熟悉一点: {length: 2}作为Array.apply第二个参数等同于[undefined, undefined]作为Array.apply第二个参数 Array.apply(null, [undefined, undefined]);
// 2 再熟悉一点:apply方法的执行结果 Array(undefined, undefined);
// 3 再再熟悉一点:Array方法直接调用和new方式调用等价 new Array(undefined, undefined);
为啥非要写那么复杂呢?
map函数并不会遍历数组中没有初始化或者被delete的元素(有相同限制还有forEach, reduce方法)。OK,疑问到此终于真相大白了:写这么“复杂”就是为了实现:创建一个长度为20,且每个元素都被初始化的数组。这样map方法就可以循环20次了。
// 被初始化的数组
Array.apply(null, { length: 20 }).map(function (val, index) {
console.log(index); // 循环20次
});
// 未被初始化的数组
Array(20).map(function (val, index) {
console.log(index); // 不会被执行
});
创建一个长度为100的数组
1.传统for循环
var arr = new Array(100);
for (var i = 0; i < arr.length; i++) {
arr[i] = i;
}
arr; // [0, 1, ..., 99]
2.ES5的实现
Object.keys(Array.apply(null, { length: 100 }));
这样似乎的确完成了功能,但是还有一个问题,此时值是字符串类型, 所以我们可以用ES5的map方法进行处理一下:
Object.keys(Array.from({ length: 100 })).map(function (item) {
return +item;
});
3.ES6的实现
//ES6中数组实例有keys、values、entries方法,
//分别用于遍历数组的索引、键值、键值对, 它们都返回遍历器对象(详细👉Iterator和for…of循环)
Object.keys(Array.from({ length: 100 })); // ["0", "1", "2", ..., "98", "99"]
Array.from(new Array(100).keys()); //Array.from其实还有一个回调函数,可以很方便遍历处理每一个数据
Array.from({ length: 100 }, (v, i) => i);
Array.from(Array(100), (v, i) => i); // [0, 1, 2, ..., 98, 99]
4.扩展运算符
[...Array(100).keys()];
//或者
[...Array.from({ length: 100 }).keys()];