美文网首页
(六)数组的扩展

(六)数组的扩展

作者: 做最棒的 | 来源:发表于2018-08-29 11:03 被阅读0次

    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]
    

    一些代码块理解
    http://www.css88.com/30-seconds-of-code/

    相关文章

      网友评论

          本文标题:(六)数组的扩展

          本文链接:https://www.haomeiwen.com/subject/wiehwftx.html