Advertisement

ES6 的扩展运算符

阅读量:

扩展语法

1. 函数 rest 参数

ES6新增了rest(剩余)参数也可称为剩余(Rest)属性该功能用于获取函数多余的可选(Optional)属性并可用作替代方案来获取额外的函数(Parameter)属性

...位于函数参数列表末尾时,则表示为rest参数;这种情况下会将剩余的所有参数汇总到一个数组中。

  • rest 参数所形成的变量是一个用于接收额外参数的数组。
    • 函数长度属性不包含 rest 参数。
复制代码
    function restFn(...arg) {
    console.log(arg);
    }
    restFn(1, true, {name: 'jsx'}, [1, 2, 3, 4])
    // [1, true, {…}, Array(4)] 
    
    // 函数的length属性,不包括 rest 参数
    console.log(restFn.length); // 0
  • 通过 rest 参数可以收集超出预期的参数并将其组织成一个数组。
  • 函数 arguments 实际上是一个类数组对象。
  • 作为类数组的对象不具备与标准数组兼容的方法。
  • 可以通过调用 Array.from() 方法将它们转换为标准的 Array 对象。
复制代码
    function replaceArgument() {
    	// 没有数组方法
    	arguments.map((item) => {
    		console.log(item)
    	}); // arguments.map is not a function
    }
    replaceArgument('jsx', 100, {title: 'arguments'}, ['html', 'css'])
    
    function restFunc(...rest) {
    	// 没有数组方法
    	rest.map((item) => {
    		console.log(item)
    	})
    }
    restFunc('jsx', 100, {title: 'arguments'}, ['html', 'css'])
  • rest 参数之后不得有其他任何参数;否则将导致错误 *
复制代码
    function morearg(...arg, title) {
    console.log(arg, title)
    }
    morearg('jsx', 'ljj', 22); // Uncaught SyntaxError

2. spread 语法

也被认为是叫做 $\texttt{spread}$ $/$ spread 的运算符。正好相反的是,在这种情况下使用的是与 \texttt{rest} / rest 参数相对立的逻辑。这种运算符的作用是将指定的可迭代对象 $arr$ 按逗号分隔开来,并将其视为独立的参数序列传递给调用函数或方法。

在函数调用等类似的表达式中出现时,在编程语言中常见于处理数据结构的情景下,“...”这一符号通常被称作 spread 语法。这种运算符的作用是将数组展开成一个列表

在函数调用或其他类似的表达式中使用省略号(...),则表示一种特定的语法机制——这被称为扩展(spread)语法,在这种情况下,它能够将一个数组元素展开为一个完整的列表。

复制代码
    let arr = ['html', 'css', 'js']
    console.log(...arr); // html css js
    
    let arr1 = ['html', ...['css', 'js']];
    console.log(arr1); // ['html', 'css', 'js']
    
    function func(...array) {
    console.log(...array)
    }
    let arr2 = ['zdj', 'ddc']
    func('jsx', 'ljj', ...arr2, ...'jsx'); // jsx ljj zdj ddc j s x
  • spread 语法可以数组合并、数组拷贝、连接多个数组、传递数组参数
复制代码
    // 合并,拷贝,连接,传递参数
    console.log(['jsx', 'ljj', ...['ddc', 'zdj']]); 
    // ['jsx', 'ljj', 'ddc', 'zdj']
    
    let arr3 = ['html', 'css', 'js']
    let newarr = [...arr3];
    console.log(newarr); //  ['html', 'css', 'js']
    
    let arr4 = ['html'];
    let arr5 = ['css', 'js']
    console.log([...arr4, ...arr5]); // ['html', 'css', 'js']
    
    function arrFunc(...arg) {
    	console.log(arg);
    }
    arrFunc([1, 2, 3])
  • spread 语法展开空数组不产生任何效果,字符串可以使用展开语法
复制代码
    let array = [];
    console.log(...array); // 不产生任何效果
    
    let hello = 'hello';
    console.log(...hello); // h e l l o

spread 语法仅针对可迭代对象,在函数调用过程中扩展运算符应置于圆括号内以避免错误的发生

复制代码
    let obj = {name: 'jsx'};
    // console.log(...obj); // Uncaught TypeError
    console.log(...document.querySelectorAll('div'))
    
    
    (...[1, 2])
    // Uncaught SyntaxError: Unexpected number
    
    console.log((...[1, 2]))
    // Uncaught SyntaxError: Unexpected number
    
    console.log(...[1, 2])
    // 1 2

3. 对象扩展运算符

对象的扩展操作符... 用于获取参数对象的所有可迭代属性并将其复制到当前对象中。

复制代码
    let obj = {name: 'jsx', age: 22};
    let newobj = {...obj};
    console.log(newobj); // {name: 'jsx', age: 22}
  • 对象的扩展运算符也可以用于数组,将数组转化为可迭代对象
复制代码
    let arr = ['html', 'css'];
    let obj1 = {...arr};
    console.log(obj1); // {0: 'html', 1: 'css'}
  • 若扩展运算符后跟的是空对象,则不会产生任何效果。
  • 当扩展运算符作用的对象并非对象时,则会将其转换为相应类型的对象(如number、boolean、null或undefined),这些类型均返回空对象。
复制代码
    // 等同于 {...Object(1)}
    console.log({...1}) // {}
    
    // 等同于 {...Object(true)}
    console.log({...true}) // {}
    
    // 等同于 {...Object(undefined)}
    console.log({...null}) // {}
    
    // 等同于 {...Object(null)}
    console.log({...undefined}) // {}
  • 对象的增强操作符仅能获得实例本身的具有的属性信息,并无法获取其原型上的相关属性*
复制代码
    function User() {
    	let name = 'jsx';
    	let sayHi = function() {};
    	this.message = 'jsx'
    }
    User.prototype.attr = '原型属性';
    let user = new User();
    let clone = {
    	...user
    }
    console.log(clone); // {message: 'jsx'}
  • 如果扩展运算符后面是字符串,它会自动转成一个类似数组的对象
复制代码
    let str = 'jsx';
    console.log({...str}); // {0: 'j', 1: 's', 2: 'x'}

个人用户的定制化字段,在执行扩展运算符时需注意以下几点:当扩展运算符内部存在与已有字段具有相同名称的情况时,默认情况下该同名字段的内容会被覆盖掉。随后设置的内容将覆盖前一版本对应名称的部分;而那些具有不同名称的字段则会被新增到当前对象中。

复制代码
    let obj3 = {now: 'js'}
    let expand = {...obj3, now: 'vue'};
    console.log(expand); // {now: 'vue'} 
    
    let obj4 = {now: 'js'}
    let expand1 = {now: 'webpack', ...obj4};
    console.log(expand1); // {now: 'js'}
  • 扩展运算符相当于调用 Object.assign() 方法,并可用于合并两个对象
复制代码
    let obj5 = {
    	class: 'js'
    };
    let objMax = {
    	name: 'jsx'
    };
    let obj6 = {
    	...obj5,
    	...objMax
    };
    console.log(obj6); // {class: 'js', name: 'jsx'}
    console.log(Object.assign({}, obj5, objMax)); // {class: 'js', name: 'jsx'}

4. 扩展运算符使用场景

  • 浅拷贝数组和对象
复制代码
    let arr = ['html', 'css']
    let newarr = [...arr];
    console.log(newarr)
    
    let obj = {name: 'jsx'};
    let newobj = {...obj};
    console.log(newobj)
  • 合并数组、连接数组
复制代码
    let arr1 = ['jsx', 'ljj'];
    let arr2 = ['html', 'css'];
    let allarr = [...arr1, ...arr2];
    console.log(allarr);
  • 替代在 apply 中使用
复制代码
    function applyFn(a, b) {
    console.log(a, b); // jsx ljj
    }
    let arr3 = ['jsx', 'ljj']
    // applyFn.apply(null, arr3);
    applyFn(...arr3)
  • 函数传递参数
复制代码
     function func(...arg){
    console.log(arg); // ['jsx', 'ljj']
    }
    func('jsx', 'ljj')
    func(...['jsx', 'ljj'])
  • 数组去重 Set() 结合使用
复制代码
    let arr4 = [2, 2, 3, 22];
    let noreplace = [...new Set(arr4)]
    console.log(arr4); // [2, 2, 3, 22]
  • 转换类数组
复制代码
    function likeArr() {
    	[...arguments].map((item) => {
    		console.log(item)
    	})
    }
    let arrover = ['html', 'css', 'js'];
    likeArr(arrover); //  ['html', 'css', 'js']
  • 解构赋值
复制代码
    let [numMin, ...numMax] = [1, 2, 3, 4];
    console.log(numMin); // 1
    console.log(numMax); // [2, 3, 4]
    
    let objover = {
    	title: '加油',
    	message: '学习',
    	date: 20220420
    }
    let {
    	title,
    	...objAll
    } = objover;
    console.log(title); // 加油
    console.log(objAll); // {message: '学习', date: 20220420}

全部评论 (0)

还没有任何评论哟~