解构
分为数组解构和对象解构,由于除了类型指定,ts的解构在ES6中基本上都实现了,所以这里相当于复习一次ES6。
数组
首先还是以代码体现最为直接
最简单的:给对应下标的值赋予名称
let arr = [1,2,3,4,5];
let [a,b,,d] = arr;
console.log(a); // 1
console.log(b); // 2
console.log(d); // 4
...rest
展开运算符:let arr = [1,2,3]; let arr2 = ['a',...arr,'b']; console.log(arr2); // ['a',1,2,3,'b'] console.log(arr2[1]); // 1
利用...
语法,可以实现数组的深拷贝:
实现深拷贝之前,来看看浅拷贝
let arr = [1,2,3,4]; let arr2 = arr; console.log(arr2); // [1,2,3,4]; arr.push(5); console.log(arr2); // [1,2,3,4,5];
原数组arr的值改变,拷贝的数组arr2也跟着改变。 这是因为只用一个等号=赋值,其实只是对引用赋值,两个数组arr和拷贝的数组arr2指向的其实是同一个内存块,因此arr改变了,arr2会对应改变;相反亦然。
想要实现深拷贝,首先除了数组的内容完全复制,还需要另开一个内存来存放复制后的数组,只有这样才会更改其中一个数组却不会对另外一个数组也跟着改变。 但展开运算符在数组中只能对可枚举属性进行拷贝,对
Objec
t和Function
类型无法拷贝,对新增元素无法拷贝。let arr1 = [1, { abj1: 333 }, { aa: function (a) { return a } }]; let arr2 = [...arr1]; console.log(arr2); // [1, { abj1: 444 }, { aa: function (a) { return a } }]; arr1.push({ abj: 333 }); console.log(arr1);// [1, { abj1: 444 }, { aa: function (a) { return a } },{ abj: 333 }]; console.log(arr2);// [1, { abj1: 444 }, { aa: function (a) { return a } }]; // 新增元素无法拷贝 arr1[1].abj1 = 444; console.log(arr2[1].abj1); // 444 console.log(arr2[2].aa(5)); // 5
除了运用
...rest
运算符进行浅拷贝,可以利用Array.prototype.slice.call()
实现数组的拷贝,但对新增元素同样无法拷贝。let arr1 = [1, { abj1: 333 }, { aa: function (a) { return a } }]; let arr2 = Array.prototype.slice.call(arr1); console.log(arr2); // [1, { abj1: 444 }, { aa: function (a) { return a } }]; arr1.push({ abj: 333 }); console.log(arr1);// [1, { abj1: 444 }, { aa: function (a) { return a } },{ abj: 333 }]; console.log(arr2);// [1, { abj1: 444 }, { aa: function (a) { return a } }]; // 新增元素无法拷贝 arr1[1].abj1 = 444; console.log(arr2[1].abj1); // 444 console.log(arr2[2].aa(5)); // 5
对象
- 简单解构:
let o = {
a: "foo",
b: 12,
c: "bar"
};
let { a, b } = o;
console.log(a,b); // foo 12
...rest
展开运算符:当展开运算中有相同属性的是,后面的值会覆盖前面的值。
let defaults = { food: "spicy", price: "$$", ambiance: "noisy" }; let search = { ...defaults, food: "rich" }; console.log(search.food); // rich
同样可以实现拷贝,但只能对可枚举属性进行拷贝,对Objec
t和Function
类型无法拷贝。
let obj = {a:1,b:2,a1:{q:11},a2:function(a){ console.log(a)}};
let obj2 = {...obj};
obj.a1.q = 3;
console.log(obj); // {a:1,b:2,a1:{q:3},a2:function(a){ console.log(a)}};
console.log(obj2.a2(3)); // undefinded
函数声明
指定类型
function f(c):void{ // ... };
解构
type c = {a:string,b:number}; function f({a,b}:c):void{ // ... };
默认值
function f({a,b=0}={a:''}):void{ // .. }; f({ a: "yes" }); // ok, default b = 0 // 并且函数具有第二个默认参数,值为0 f(); // ok, default to {a: ""}, which then defaults b = 0 // 当参数为空的时候,默认返回一个对象{a:''} f({}); // error, 'a' is required if you supply an argument // 报错,因为当参数是一个对象的时候,对象中的属性a并没有默认值。