Javascript学习---解构赋值

解构赋值是一种特殊的语法,它允许我们将数组或则对象“解压”到一堆变量里面。

数组解构

我们可以将数组“解压”到变量中去,例如:
// we have an array with the name and surname
let arr = ["Ilya", "Kantor"]

// destructuring assignment
let [firstName, surname] = arr;

alert(firstName); // Ilya
alert(surname);  // Kantor
当它与数组的一些方法组合起来会很方便,例如:
let [firstName, surname] = "Ilya Kantor".split(' ');

解构不影响元原数组

解构数组其实就是将数组元素赋值到新的变量里,而原数组并不会被影响,解构原理如下例子:
// let [firstName, surname] = arr;
let firstName = arr[0];
let surname = arr[1];
解构只是上面例子的简写形式

忽略指定元素

在解构数组的时候,如果不需要某些元素,我们可以手动忽略掉,例如:
// first and second elements are not needed
let [, , title] = ["Julius", "Caesar", "Consul", "of the Roman Republic"];

alert( title ); // Consul

解构任何可迭代对象

我们除了解构数组外,任何可迭代对象都是可以被解构的,例如String,Map,Set
let [a, b, c] = "abc"; // ["a", "b", "c"]
let [one, two, three] = new Set([1, 2, 3]);


在左边指定属性

let user = {};
[user.name, user.surname] = "Ilya Kantor".split(' ');

alert(user.name); // Ilya

使用Obejct.entries()进行遍历解构

Obejct.entries()方法以数组的格式返回对象的属性名和值,我们可以使用它进行遍历解构,例如:
let user = {
  name: "John",
  age: 30
};

// loop over keys-and-values
for (let [key, value] of Object.entries(user)) {
  alert(`${key}:${value}`); // name:John, then age:30
}

对于Map也是一样的,例如:
let user = new Map();
user.set("name", "John");
user.set("age", "30");

for (let [key, value] of user.entries()) {
  alert(`${key}:${value}`); // name:John, then age:30
}

解构到剩余的变量里

如果我们需要解构多个变量里,我们可以不一一写出这些变量名,使用“...”来接收解构的元素,例如:
let [name1, name2, ...rest] = ["Julius", "Caesar", "Consul", "of the Roman Republic"];

alert(name1); // Julius
alert(name2); // Caesar

alert(rest[0]); // Consul
alert(rest[1]); // of the Roman Republic
alert(rest.length); // 2

默认值

如果我们要解构的数组为空,那么用于接收解构结果的参数的值默认为undefined,例如:
let [firstName, surname] = [];

alert(firstName); // undefined

当然,我们可以手动设置默认值,例如:
// default values
let [name = "Guest", surname = "Anonymous"] = ["Julius"];

alert(name);    // Julius (from array)
alert(surname); // Anonymous (default used)

默认值除了一般数据类型外,也可以是函数调用,例如:
// runs only prompt for surname
let [name = prompt('name?'), surname = prompt('surname?')] = ["Julius"];

alert(name);    // Julius (from array)
alert(surname); // whatever prompt gets

对象解构

对象解构会默认将属性名解构到对应相同名字的变量中,若名字不同则为undefined,例如:
let options = {
  title: "Menu",
  width: 100,
  height: 200
};

let {title, width, height} = options;

alert(title);  // Menu
alert(width);  // 100
alert(height); // 200
当然打乱顺序也无所谓,因为它会自动根据属性名关联,例如:
// changed the order of properties in let {...}
let {height, width, title} = { title: "Menu", height: 200, width: 100 }

接受变量名修改

如果你想自定义解构后的变量名,你可以这样做:
let options = {
  title: "Menu",
  width: 100,
  height: 200
};

// { sourceProperty: targetVariable }
let {width: w, height: h, title} = options;

// width -> w
// height -> h
// title -> title

alert(title);  // Menu
alert(w);      // 100
alert(h);      // 200
这时候width就被修改为w了,我们就可以使用修改后的变量名w

默认值

跟数组解构一样,对象解构也可以设置默认值,例如:
let options = {
  title: "Menu"
};

let {width = 100, height = 200, title} = options;

alert(title);  // Menu
alert(width);  // 100
alert(height); // 200

也可以使用函数设置默认值,例如:
let options = {
  title: "Menu"
};

let {width = prompt("width?"), title = prompt("title?")} = options;

alert(title);  // Menu
alert(width);  // (whatever you the result of prompt is)

跟上面的冒号方式修改接受变量名结合起来就是:
let options = {
  title: "Menu"
};

let {width: w = 100, height: h = 200, title} = options;

alert(title);  // Menu
alert(w);      // 100
alert(h);      // 200

剩余接受变量操作(rest)

let options = {
  title: "Menu",
  height: 200,
  width: 100
};

let {title, ...rest} = options;

// now title="Menu", rest={height: 200, width: 100}
alert(rest.height);  // 200
alert(rest.width);   // 100

没有let情况

如果我们使用一下方式进行对象解构则会报错,例如:
let title, width, height;

// error in this line
{title, width, height} = {title: "Menu", width: 200, height: 100};
因为Javascript会把{...}里的内容当做代码块处理,比如这样:
{
  // a code block
  let message = "Hello";
  // ...
  alert( message );
}
为了解决这种问题,我们可以使用小括号把解构代码括起来,例如:
let title, width, height;

// okay now
({title, width, height} = {title: "Menu", width: 200, height: 100});

alert( title ); // Menu

嵌套解构

如果一个对象或者数组里嵌套了其他对象或数组,我们可以声明对应的结构的变量来接收解构结果,例如:
let options = {
  size: {
    width: 100,
    height: 200
  },
  items: ["Cake", "Donut"],
  extra: true    // something extra that we will not destruct
};

// destructuring assignment on multiple lines for clarity
let {
  size: { // put size here
    width,
    height
  },
  items: [item1, item2], // assign items here
  title = "Menu" // not present in the object (default value is used)
} = options;

alert(title);  // Menu
alert(width);  // 100
alert(height); // 200
alert(item1);  // Cake
alert(item2);  // Donut

如果我们只需要特定的解构元素,可以这么写:
// take size as a whole into a variable, ignore the rest
let { size } = options;

利用解构来设置函数参数

设想一下,如果一个函数有多个参数,并且有些参数还是可选的,那我们应该怎样来调用,例如这样:
function showMenu(title = "Untitled", width = 200, height = 100, items = []) {
  // ...
}

showMenu("My Menu", undefined, undefined, ["Item1", "Item2"]);
但是这样写太麻烦且可读性差,因此我们可以使用解构的方式来填充参数,例如:
// we pass object to function
let options = {
  title: "My menu",
  items: ["Item1", "Item2"]
};

// ...and it immediately expands it to variables
function showMenu({title = "Untitled", width = 200, height = 100, items = []}) {
  // title, items – taken from options,
  // width, height – defaults used
  alert( `${title} ${width} ${height}` ); // My Menu 200 100
  alert( items ); // Item1, Item2
}

showMenu(options);
或者自定义接受变量名:
let options = {
  title: "My menu",
  items: ["Item1", "Item2"]
};

function showMenu({
  title = "Untitled",
  width: w = 100,  // width goes to w
  height: h = 200, // height goes to h
  items: [item1, item2] // items first element goes to item1, second to item2
}) {
  alert( `${title} ${w} ${h}` ); // My Menu 100 200
  alert( item1 ); // Item1
  alert( item2 ); // Item2
}

showMenu(options);

有一点要注意的是,解构法设置函数参数时会默认函数(showMenu())存在参数,如果我们在调用函数是没有设置参数(也就是被解构的对象)就会报错,例如:
showMenu({});


showMenu(); // this would give an error
为了解决这种问题,我们可以在声明函数的时候就设置默认值,例如:
// simplified parameters a bit for clarity
function showMenu({ title = "Menu", width = 100, height = 200 } = {}) {
  alert( `${title} ${width} ${height}` );
}

showMenu(); // Menu 100 200



  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值