1、扩展运算符的应用
1.1) 复制数组
const a1 = [1, 2];
// 写法一
const a2 = [...a1];
// 写法二
const [...a2] = a1;
ES5回顾
const a1 = [1, 2];
const a2 = a1;
const a3 =a1.concat(1,2);
a2[0] = 2;
a1 // [2, 2]
1.2) 合并数组
const arr1 = ['a', 'b'];
const arr2 = ['c'];
const arr3 = ['d', 'e'];
// ES5 的合并数组
arr1.concat(arr2, arr3);
// [ 'a', 'b', 'c', 'd', 'e' ]
// ES6 的合并数组
[...arr1, ...arr2, ...arr3]
// [ 'a', 'b', 'c', 'd', 'e' ]
1.3) 与解构赋值结合
// ES5
a = list[0], rest = list.slice(1)
// ES6
[a, ...rest] = list
const [first, ...rest] = [1, 2, 3, 4, 5];
first // 1
rest // [2, 3, 4, 5]
const [first, ...rest] = [];
first // undefined
rest // []
const [first, ...rest] = ["foo"];
first // "foo"
rest // []
1.4) 字符串
[...'hello']
// [ "h", "e", "l", "l", "o"
1.5) 实现了 Iterator 接口的对象
切记,只有继承了iterator接口的对象才能用扩展运算符
let arrayLike = {
'0': 'a',
'1': 'b',
'2': 'c',
length: 3
};
// TypeError: Cannot spread non-iterable object.
let arr = [...arrayLike];
let arrayLike = {
'0': 'a',
'1': 'b',
'2': 'c',
length: 3
};
// TypeError: Cannot spread non-iterable object.
let arr =Array.from(arrayLike);// [...arrayLike];
console.log(arr);
1.6) Map 和 Set 结构,Generator 函数
扩展运算符内部调用的是数据结构的 Iterator 接口,因此只要具有 Iterator 接口的对象,都可以使用扩展运算符,比如 Map 结构。
自己看
2、Array.from()
2.1) 类数组转化为数组
let arrayLike = {
'0': 'a',
'1': 'b',
'2': 'c',
length: 3
};
// ES5的写法
var arr1 = [].slice.call(arrayLike); // ['a', 'b', 'c']
// ES6的写法
let arr2 = Array.from(arrayLike); // ['a', 'b', 'c']
// NodeList对象
let ps = document.querySelectorAll('p');
Array.from(ps).filter(p => {
return p.textContent.length > 100;
});
Array.from('hello')
// ['h', 'e', 'l', 'l', 'o']
let namesSet = new Set(['a', 'b'])
Array.from(namesSet) // ['a', 'b']
只要是部署了 Iterator 接口的数据结构,Array.from都能将其转为数组
// arguments对象
function foo() {
const args = [...arguments];
}
// NodeList对象
[...document.querySelectorAll('div')]
扩展运算符(...)也可以将某些数据结构转为数组
2.2) 真正的数组,Array.from会返回一个一模一样的新数组
Array.from([1, 2, 3])
// [1, 2, 3]
返回的数组是新数组,属于浅拷贝
2.3) 任何有length属性的对象,都可以通过Array.from方法转为数组,而此时扩展运算符就无法转换
Array.from({ length: 3 });
// [ undefined, undefined, undefined
2.4) Array.from还可以接受第二个参数,作用类似于数组的map方法,用来对每个元素进行处理,将处理后的值放入返回的数组
Array.from(arrayLike, x => x * x);
// 等同于
Array.from(arrayLike).map(x => x * x);
const abc = [1, 2, 3];
const bbc = Array.from([1, 2, 3], (x) => x * x)
console.log(bbc);
console.log(abc);
//
3、Array.of()
Array.of方法用于将一组值,转换为数组。
Array.of(3, 11, 8) // [3,11,8]
Array.of(3) // [3]
Array.of(3).length // 1
行为差异
Array() // []
Array(3) // [, , ,]
Array(3, 11, 8) // [3, 11, 8]
Array.of基本上可以用来替代Array()或new Array(),并且不存在由于参数不同而导致的重载。它的行为非常统一。
Array.of() // []
Array.of(undefined) // [undefined]
Array.of(1) // [1]
Array.of(1, 2) // [1, 2]
?怎么定义数组长度
4、数组实例的 copyWithin()
接受三个参数。
target(必需):从该位置开始替换数据。如果为负值,表示倒数。
start(可选):从该位置开始读取数据,默认为 0。如果为负值,表示倒数。
end(可选):到该位置前停止读取数据,默认等于数组长度。如果为负值,表示倒数。
[1, 2, 3, 4, 5].copyWithin(0, 3)
// [4, 5, 3, 4, 5]
更多内容,自己看书
5、数组实例的 fill()
fill方法使用给定值,填充一个数组。
['a', 'b', 'c'].fill(7)
// [7, 7, 7]
new Array(3).fill(7)
// [7, 7, 7]
//fill方法还可以接受第二个和第三个参数,用于指定填充的起始位置和结束位置。
['a', 'b', 'c'].fill(7, 1, 2)
// ['a', 7, 'c']
如果填充的类型为对象,那么被赋值的是同一个内存地址的对象,而不是深拷贝对象
let arr = new Array(3).fill({name: "Mike"});
arr[0].name = "Ben";
arr
// [{name: "Ben"}, {name: "Ben"}, {name: "Ben"}]
let arr = new Array(3).fill([]);
arr[0].push(5);
arr
// [[5], [5], [5]]
实例
// 列表数据处理
setInputValue = (data = []) => {
const base = {
keyword: '',
status: 0
};
const len = data.length;
if (len > 0) {
const sortArr = data.sort((a, b) => b.status - a.status);
if (maxLen === len) {
return sortArr;
}
const addArr = Array(maxLen - len).fill(base);
return sortArr.concat(addArr);
}
return Array(maxLen).fill(base);
}
triggerChange = (inputValue) => {
const self = this;
const onChange = this.props.onChange;
self.setState({ inputValue });
if (onChange) {
onChange(inputValue);
}
self.forceUpdate();
}
checkText = (e) => {
const self = this;
const target = e.target;
const value = target.value.trim(); // 输入的值
const index = Number(target.dataset.index); // 当前的索引
const { inputValue } = self.state;
const item = Object.assign({}, inputValue[index]);
item.keyword = value;
item.status = 0;
inputValue[index] = item;
self.triggerChange(inputValue);
}
6、数组实例的 entries(),keys() 和 values()
6.1) 数组中是量值,用这些方法会输出什么
//在浏览器中执行这些方法
const abc = [1, 2, 3];
console.log(...abc.keys()); // 0 1 2
console.log(...abc.values()); // 1 2 3
console.log(...abc.entries()); // (2) [0, 1] (2) [1, 2] (2) [2, 3]
为什么会这样
6.2) 数组中是对象形式,用这些方法会输出什么
//在浏览器中执行这些方法
const abc = [{
id:1,
name:'liang'
},{
id:2,
name:'xiao'
},{
id:3,
name:'hu'
}];
console.log(...abc.keys()); //0 1 2
console.log(...abc.values());
// {id: 1, name: "liang"} {id: 2, name: "xiao"} {id: 3, name: "hu"}
console.log(...abc.entries());
//[ 0, { id: 1, name: 'liang' } ] [ 1, { id: 2, name: 'xiao' } ] [ 2, { id: 3, name: 'hu' } ]
{id: 1, name: "liang"} {id: 2, name: "xiao"} {id: 3, name: "hu"}
6.3) 遍历
如果不使用for...of循环,可以手动调用遍历器对象的next方法,进行遍历。
let letter = ['a', 'b', 'c'];
let entries = letter.entries();
console.log(entries.next().value); // [0, 'a']
console.log(entries.next().value); // [1, 'b']
console.log(entries.next().value); // [2, 'c']
这些方法用在什么地方?
7、数组实例的 includes()
Array.prototype.includes方法返回一个布尔值,表示某个数组是否包含给定的值,与字符串的includes方法类似
[1, 2, 3].includes(2) // true
[1, 2, 3].includes(4) // false
[1, 2, NaN].includes(NaN) // true
该方法的第二个参数表示搜索的起始位置,默认为0。如果第二个参数为负数,则表示倒数的位置,如果这时它大于数组长度(比如第二个参数为-4,但数组长度为3),则会重置为从0开始。
[1, 2, 3].includes(3, 3); // false
[1, 2, 3].includes(3, -1); // true
没有该方法之前,我们通常使用数组的indexOf方法,检查是否包含某个值。
if (arr.indexOf(el) !== -1) {
// ...
}
8 数组实例的 flat(),flatMap()
自己看
自己想想和我以前分享的一个方法有什么异同
const m = ['a','b','c',['d','e','f']];
m.join(',');
9 数组的空位
很重要,自己看
10 应用
const fibonacci = n =>
Array.from({ length: n }).reduce(
(acc, val, i) => acc.concat(i > 1 ? acc[i - 1] + acc[i - 2] : i),
[]
);
const fibonacci = n =>
Array(n).fill(0).reduce(
(acc, val, i) => acc.concat(i > 1 ? acc[i - 1] + acc[i - 2] : i),
[]
);
console.log(fibonacci(10)); // [0, 1, 1, 2, 3, 5]
网友评论