天天看點

ES6-...(spreed&rest)運算符

ES6-...收集/展開運算符

      • ...運算符的作用
      • ...運算符分類:讀和寫,ES6和ES7
      • ES6中寫的場景
      • ES6中讀的操作(spreed)
      • ES7 ...運算符對于對象的處理

…運算符的作用

簡化書寫長度,提升開發效率           

複制

…運算符分類:讀和寫,ES6和ES7

  • 讀的場景

    var arg = [1,2,3]; console.log(…arg); -展開作用

  • 寫的場景

    function test (…arg){}; test(1,2,3);-收集作用

  • ES6

    主要作用在數組上

  • ES7

    主要作用在對象上

ES6中寫的場景

我們先來看一個求平均分的案例(需要去掉最高分和最低分)

此處我們是使用的是ES5中的正常寫法

function average(){
		var averageNumber = 0;
		//将arguments轉化為數組
		var arr = [].slice.call(arguments);
		//數組按照從小到大排序
		arr.sort(function(a, b){
				return a - b;
		});
		arr.pop();
		arr.shift();
		for(var i = 0; i < arr.length; i++){
			averageNumber += arr[i];
		}
		return averageNumber /= arr.length;
	}           

複制

現在來看看ES6中的rest運算符

寫的場景

function average(...arg){
		var averageNumber = 0;
		//數組按照從小到大排序
		arg.sort(function(a, b){
				return a - b;
		});
		//去掉第一個和最後一個
		arg.pop();
		arg.shift();
		for(var i = 0; i < arg.length; i++){
			averageNumber += arg[i];
		}
		return averageNumber /= arg.length;
	}
	console.log(average(3, 1, 4, 2));//2.5           

複制

此處就是rest運算符的作用;

  • 将參數收集起來,收集方式為将參數放入數組存入arg中,是以,下面才可以直接調用數組的方法

再擴充一下寫的操作

下面兩個案例會讓使用更豐富一些

function print(a, b, ...arg){
		console.log(a, b, arg);
	}
	print('a', 'b', 1, 2, 3);           

複制

ES6-...(spreed&amp;rest)運算符

rest運算符前面是可以放指定參數的,并且不會被收集到數組當中

另外一個案例

function print(a, b, ...arg, d){
		console.log(a, b, arg);
	}
	print('a', 'b', 1, 2, 3,'d');           

複制

ES6-...(spreed&amp;rest)運算符

從錯誤上我們可以了解到rest運算符需要放在參數的最後一位

ES6中讀的操作(spreed)

先從一個案例入手

let arr = [1, 2, 3, 4, 5];
	console.log(arr); //毫無疑問此處應該列印[1, 2, 3, 4, 5];
	console.log(...arr);//但是再spreed運算符後,會變成散列的值: 1, 2, 3, 4, 5           

複制

再深入一下使用

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

複制

這裡arr3通過使用spreed運算符,合成了一個數組,其原理也是通過數組的concat方法拼接在一起

我們再看一個求和的案例,現在按照子產品拆分開

function getComputed(...arg){
		arg.sort(function(a, b){
			return a - b;
		});
		arg.shift();
		arg.prp();
		//采用spreed,将數組轉成了散列的值
		return getSum(...arg);
	}
	//采用了rest運算符,将散列的值收到數組當中
	function getSum(...arg){
		let sum = 0;
		for(let i = 0; i < arg.length; i++){
			sum += arg[i];
		}
		return sum;
	}           

複制

從上述的場景中,我們通過第一個函數處理數組(排序,去掉最高分和最低分),再求和

通過…運算發大大的簡化了我們的操作

ES7 …運算符對于對象的處理

  • 淺層克隆
let company = {
		name: 'xinhangdao',
		age: 15
	}
	let department = {
		leader: {
			name: 'zhangsan',
			age: '18'
		}
		age:  20
	}
	let obj = {
		...company,
		...department
	}
	console.log(obj);
	obj.leader.name = "zhangsan";
	console.log(obj.leader);//{name: "zhangsan", age: 18}
	console.log(department.leader);//{name: "zhangsan", age: 18}           

複制

ES6-...(spreed&amp;rest)運算符

這是列印的結果,但是,這裡是淺層克隆,如果修改leader的資料,deparment中的資料也會修改。

實質是,obj拿到的leader是department中leader的引用

要達到深層克隆的效果,有如下辦法

let company = {
		name: 'xinhangdao',
		age: 15
	}
	let leader: {
			name: 'cg',
			age: '18'
		}
	let department = {
		age:  20
	}
	let obj = {
		...company,
		...department,
		leader:{
			...leader
		}
	}
	console.log(obj);
	obj.leader.name = "zhangsan";
	console.log(obj.leader);//{name: "zhangsan", age: 18}
	console.log(leader);//{name: "cg", age: 18}           

複制

可以通過leader的克隆原始值的方式來深度克隆

但是,此方法,當一個對象有很多層級的時候就不适用了

深度克隆的方法二: js自己寫一個deepClone的方法,主要思想是采用遞歸

深度克隆的方法三: 這是一個劍走偏鋒的方法,采用json來做

let obj = {
		name: 'zhangsan',
		age: 18
	}
	let obj1 = JSON.parse(JSON.stringify(obj))           

複制

但是此方法有缺點:當對象中具有函數的,正規表達式,或者一些特殊的對象,例如new Date()等,可能會使原來的屬性丢失,或者改變原有的面貌