ES6 之展开运算符 (…) 原理与应用

发布于 2021-08-03  149 次阅读


展开运算符,将一个数组转为用逗号分隔的参数序列

原理

工作原理:展开运算符或三个点,接受一个数组数组或通常是可迭代的[... arrayOrIterable]并将数组元素分解,并使用这些分解部分构造一个新数组。

1.如果是数组,使用apply传入参数结构;
2.如果是object,使用内置的工具函数把属性拷贝出来。

源码:

const arr = [1, 2, 3]
const obj = {
    name: 'huxinfeng'
}
console.log(...arr);
console.log({ ...obj });

方法一、TS编译JS

编译后:

"use strict";
var __assign = (this && this.__assign) || function () {
    __assign = Object.assign || function(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
            s = arguments[i];
            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
                t[p] = s[p];
        }
        return t;
    };
    return __assign.apply(this, arguments);
};
var arr = [1, 2, 3];
var obj = {
    name: 'huxinfeng'
};
// 如果是数组,使用apply传入参数结构
console.log.apply(console, arr);
// 如果是object,使用内置的工具函数把属性拷贝出来
console.log(__assign({}, obj));

方法二、webpack + @babel 编译处理

下面这段代码是经过@babel/core @babel/cli @babel/preset-env 处理的。

编译后:

/******/
(function () {
    // webpackBootstrap
    /******/
    "use strict";
    var __webpack_exports__ = {};
    /*!**********************!*\
    !*** ./src/index.ts ***!
    \**********************/

    var _console;

    function ownKeys(object, enumerableOnly) {
        var keys = Object.keys(object);
        if (Object.getOwnPropertySymbols) {
            var symbols = Object.getOwnPropertySymbols(object);
            if (enumerableOnly) {
                symbols = symbols.filter(function (sym) {
                    return Object.getOwnPropertyDescriptor(object, sym).enumerable;
                });
            }
            keys.push.apply(keys, symbols);
        }
        return keys;
    }

    function _objectSpread(target) {
        for (var i = 1; i < arguments.length; i++) {
            var source = arguments[i] ! = null ? arguments[i] : {};
            if (i % 2) {
                ownKeys(Object(source), true).forEach(function (key) {
                    _defineProperty(target, key, source[key]);
                });
            } else if (Object.getOwnPropertyDescriptors) {
                Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
            } else {
                ownKeys(Object(source)).forEach(function (key) {
                    Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
                });
            }
        }
        return target;
    }

    function _defineProperty(obj, key, value) {
        if (key in obj) {
            Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true });
        } else {
            obj[key] = value;
        }
        return obj;
    }

    var arr = [1, 2, 3];
    var obj = {
        name: 'huxinfeng',
    };

    // 如果是数组,使用apply传入参数结构
    (_console = console).log.apply(_console, arr);

    // 如果是object,使用内置的工具函数把属性拷贝出来
    console.log(_objectSpread({}, obj));
    /******/
})();
//# sourceMappingURL=main.min.js.map

应用

1.合并数组

let a = [1, 2, 3];
let b = [4, 5, 6];
let c = [...a, ...b]; // [1,2,3,4,5,6]

2.替代apply

function f(a, b, c) {
    console.log(a, b, c);
}
let args = [1, 2, 3];
// 以下三种方法结果相同
f.apply(null, args); //1 2 3
f(...args);
f(1, 2, 3);

function f2(...args) {
    console.log(args);
}
f2(1, 2, 3); // [1,2,3]

function f3() {
    console.log(Array.from(arguments));
}
f3(1, 2, 3); // [1,2,3]

3.解构赋值

let a = [1, 2, 3, 4, 5, 6];
let [c, ...d] = a;
console.log(c); // 1
console.log(d); // [2,3,4,5,6]
//展开运算符必须放在最后一位

4.字符串转为数组,正确识别 32 位的 Unicode 字符

[..."siva"]; // ['s','i','v','a']
[..."x\uD83D\uDE80y"].length; // 3

5.具有 Iterator 接口的对象,转换成数组

var nodelist = document.querySelectorAll("div");
console.log([...nodelist]); // 转化成数组

var map = new Map([
    [1, 11],
    [2, 22],
    [3, 33],
]);
console.log(map.keys());      // [Map Iterator] { 1, 2, 3 }
console.log(...map.keys());   // 1 2 3
console.log([...map.keys()]); // [ 1, 2, 3 ]

6.浅拷贝

//数组
var a = [1, 2, 4];
var b = [...a];
a.push(6);
console.log(b);   // [1,2,4]

//对象
var a = { a: 1 };
var b = { ...a };
a.a = 5;
console.log(b.a); // 1

博主好穷啊,快点支助一下吧 ε = = (づ′▽`)づ