我们相信:世界是美好的,你是我也是。平行空间的世界里面,不同版本的生活也在继续...

本文基于js来说明一下三个点扩展运算符的用法,在很多编程语言中,都有这个三个点运算符,大体的用途都是用于解包一些数据。在具体的实际操作中,总还是会有一些出乎意料的事情发生的。如果您也有兴趣,可以随着苏南大叔的思路,来看看三个点的具体用法。

苏南大叔:js代码,三个点扩展运算符如何解包数据array/object/string? - 三个点操作符dotdotdot
js代码,三个点扩展运算符如何解包数据array/object/string?(图10-1)

大家好,这里是苏南大叔的平行空间笔记本博客,这里记录苏南大叔和计算机代码的故事。本文描述三个点运算符的故事。测试环境:node@16.14.2。理论上浏览器环境下也是可以运行的,不过具体没实验。

解包用法

基本用法就是用于数据的解包,比如对arrayobjectstring的解包操作。

console.log(...[1,2,3,4,5,6])       // 1 2 3 4 5 6
//console.log(...{"id":5})          // error
console.log([...["hello"]])         // [ 'hello' ]
console.log({...{"id":5}})          // {"id":5}
console.log([...'hello']);          // ['h', 'e', 'l', 'l','o']
console.log({...'hello'});          // { '0': 'h', '1': 'e', '2': 'l', '3': 'l', '4': 'o' }

苏南大叔:js代码,三个点扩展运算符如何解包数据array/object/string? - dot-dot-dot-1
js代码,三个点扩展运算符如何解包数据array/object/string?(图10-2)

合并用法

这里其实还可以把这个解包操作,变成合并数据的操作目的,这个时候就有一些不合常规的操作了。

合并数组array

数组array合并,数组元素之间并不相互覆盖。

var arr1 = [0, [1, 2], 3 ];
var arr2 = [4, [5, 6, 7] ];
arr3 = [...arr1,...arr2];
console.log(arr3);                    // [ 0, [ 1, 2 ], 3, 4, [ 5, 6, 7 ] ]

苏南大叔:js代码,三个点扩展运算符如何解包数据array/object/string? - dot-dot-dot-2
js代码,三个点扩展运算符如何解包数据array/object/string?(图10-3)

合并对象object

对象object合并,同keyobject属性,会产生覆盖关系。而且是那种简单的覆盖,并不考虑深度的元素覆盖(合并)。

var arr1 = [0, [1, 2], 3 ];
var arr2 = [4, [5, 6, 7] ];
var obj3 = {...arr1,...arr2};          // { '0': 4, '1': [ 5, 6, 7 ], '2': 3 }
console.log(obj3);

苏南大叔:js代码,三个点扩展运算符如何解包数据array/object/string? - dot-dot-dot-3
js代码,三个点扩展运算符如何解包数据array/object/string?(图10-4)

赋值变量

可以把解包的数据赋值给新的变量,但是带三个点的变量位置是有特殊规定的,需要放置在最后面。如果是解包个数组或者字符串的话,那么变量的名字是可以随便写的。

var [a, b, ...c] = "hello";
console.log(a,b,c);                        // h e [ 'l', 'l', 'o' ]
var [a, b, ...c] = [1, 2, 3, 4, 5];
console.log(a,b,c);                        // 1 2 [ 3, 4, 5 ]
// var [...abc, c]  = [1, 2, 3, 4, 5];     // error
// var [a, ...b, c] = [1, 2, 3, 4, 5];     // error

苏南大叔:js代码,三个点扩展运算符如何解包数据array/object/string? - dot-dot-dot-5
js代码,三个点扩展运算符如何解包数据array/object/string?(图10-5)

但是,如果解包的是个对象的话,那么变量名字和属性名称必须对应,否则提取不到数据,会得到一个undefined。并且,只要注意变量的名字需要对应外,名字的顺序是无所谓的,(当然带三个点的变量一定要放在最后,并且叫啥都行)。

var {a, b, ...c} = {a:"aaa",b:"bbb",c:"ccc",d:"ddd"} 
console.log(a,b,c);           // aaa bbb { c: 'ccc', d: 'ddd' }
var {a, bb, ...c} = {a:"aaa",b:"bbb",c:"ccc",d:"ddd"}  
console.log(a,bb,c);          // aaa undefined { b: 'bbb', c: 'ccc', d: 'ddd' }
var {b, c, ...a} = {a:"aaa",b:"bbb",c:"ccc",d:"ddd"} 
console.log(a,b,c);           // { a: 'aaa', d: 'ddd' } bbb ccc
//var [a, b, ...c] = {a:"aaa",b:"bbb",c:"ccc",d:"ddd"}
//console.log(a,b,c);         // is not iterable
注意写法,{}而不是[]

苏南大叔:js代码,三个点扩展运算符如何解包数据array/object/string? - dot-dot-dot-6
js代码,三个点扩展运算符如何解包数据array/object/string?(图10-6)

函数的参数赋值

这里也分为两种情况,一种是函数定义的时候使用三个点,一种是函数调用的时候使用三个点。

函数定义使用三个点

在定义函数的时候使用三个点,这个和传入了一个数组操作是一样的。

function _sum(...arr) {
    let ret = 0;
    for (var i of arr) { ret += i; }
    return ret;
}
a = _sum(1, 2, 3)             // 6
b = _sum(1, 2, 3, 4, 5)       // 15
console.log(a, b)

苏南大叔:js代码,三个点扩展运算符如何解包数据array/object/string? - dot-dot-dot-7
js代码,三个点扩展运算符如何解包数据array/object/string?(图10-7)

函数调用使用三个点

function f(x, y, z) {
    console.log(x, y, z)
}
f(1, ...[2, 3], 4, 5);         // 1 2 3
var args = [1, 2, 3];
f(...args);                    // 1 2 3
f.apply(null, args);           // 1 2 3
f.apply(null, args) 这是一个新的写法。

苏南大叔:js代码,三个点扩展运算符如何解包数据array/object/string? - dot-dot-dot-8
js代码,三个点扩展运算符如何解包数据array/object/string?(图10-8)

切断引用关系

测试代码:

var var1 = ["sunan","大叔"]
var var2 = [...var1]
var2[0] = "苏南"
console.log(var1,var2)                         // [ 'sunan', '大叔' ] [ '苏南', '大叔' ]

var var1 = ["sunan","大叔"]
var var2=  ["sunan","大叔"]
var2[0] = "苏南"
console.log(var1,var2)                         // [ 'sunan', '大叔' ] [ '苏南', '大叔' ]

var var1 = ["sunan","大叔"]
var var2 = var1
var2[0] = "苏南"
console.log(var1,var2)                          // [ '苏南', '大叔' ] [ '苏南', '大叔' ]

苏南大叔:js代码,三个点扩展运算符如何解包数据array/object/string? - dot-dot-dot-10
js代码,三个点扩展运算符如何解包数据array/object/string?(图10-9)

虽然把一个数组解包再封包,和原来没有啥区别。但是,切断了js默认自带的引用关系,是一个完全独立的变量了。对原变量的修改,并不会影响到第二个变量。下面的代码同理:

var var1 = {"name":"sunan大叔"}
var var2 = {...var1}
var1.name= "苏南大叔"
console.log(var1,var2)                         // { name: '苏南大叔' } { name: 'sunan大叔' }

var var1 = {"name":"sunan大叔"}
var var2=  {"name":"sunan大叔"}
var1.name= "苏南大叔"
console.log(var1,var2)                         // { name: '苏南大叔' } { name: 'sunan大叔' }

var var1 = {"name":"sunan大叔"}
var var2 = var1
var1.name= "苏南大叔"
console.log(var1,var2)                          // { name: '苏南大叔' } { name: '苏南大叔' }

苏南大叔:js代码,三个点扩展运算符如何解包数据array/object/string? - dot-dot-dot-11
js代码,三个点扩展运算符如何解包数据array/object/string?(图10-10)

相关链接

总结

更多经验文章,请点击下面的链接:

如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。

 【福利】 腾讯云最新爆款活动!1核2G云服务器首年50元!

 【源码】本文代码片段及相关软件,请点此获取更多信息

 【绝密】秘籍文章入口,仅传授于有缘之人   js