前言
嘟三~ 嘟三~ 今日份广播题目:“怎么让JavaScript越来越6”。接下来,小菜鸡本人将和大家一起来探讨ES6-ES13的那些酷酷的新特性,从这次广播开始,你也可以炫耀:“这个ES新特性我都用得溜溜的!”
一、ES对象的增强
ES6让JavaScript对象有了一种全新的魅力,ES6中对 对象字面量 进行了增强,称之为 Enhanced object literals(增强对象字面量)。
1.1. 属性的简写
你有没有过这样的经历?当你需要创建一个对象,你发现对象的属性名称和对应的变量名称恰好是一样的,你是否感到这样重复编码的过程非常痛苦?在ES6中,这问题已经被解决啦。
var name = "why" var age = 18 // ES5的写法 var obj1 = { name: name, age: age } // ES6的增强写法 var obj2 = { name, age }
1.2. 方法的简写
对象不仅被赋予了简化属性的能力,而且对象的方法也可以多了简写方式,就像一个新家具能更好地装饰你的房子一样。
// ES5的方法写法 var info1 = { foo: function() { }, bar: function() { } } // ES6的增强写法 var info2 = { foo() { }, bar() { } }
1.3. 计算属性名
有时候,我们可能希望动态地设置对象的属性名。可以想象一下,这就像你的家有一扇神奇的门,门的名字不是固定的,而是根据你的需要改变。
var name = "three" var obj = { one: 1, two: 2 } obj[name] = 3
在ES6中,我们可以直接在字面量中编写计算属性名:
英文称之为 Computed Property Names
var name = "three" var obj = { one: 1, two: 2, [name]: 3 } console.log(obj)
二、函数知识补充
1.1. 函数的默认值设置
在ES6之前,我们编写的函数参数是没有默认值的,所以我们在编写函数时,如果有下面的需求:
- 传入了参数,那么使用传入的参数
- 没有传入参数,那么使用一个默认值
通常我们会进行如下方式的实现:
function foo(x, y) { x = x || 20 y = y || 30 console.log(x, y) } foo(50, 100) // 50 100 foo() // 20 30
其实这种做法是有弊端的,如果我们传入null、0、空字符串,那么会认为需要使用默认值:
foo(null, "") // 20, 30
而在ES6中,我们允许给函数一个默认值:
function foo(x = 20, y = 30) { console.log(x, y) } foo(50, 100) // 50 100 foo() // 20 30
我们使用ES6默认值的写法不仅仅可以避免上面的问题,而且代码的阅读性也会更强:
其实ES6的默认值转化后是如下的代码
function foo() { var x = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 20; var y = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 30; console.log(x, y); }
默认值也可以和解构一起来使用
// 写法一: function foo({name, age} = {name: "why", age: 18}) { console.log(name, age) } // 写法二: function foo({name = "why", age = 18} = {}) { console.log(name, age) } foo()
1.2. 函数的剩余参数
有时,作为一个厨师,你可能会面临一个问题:你不知道会收到多少食材(参数)。ES6解决了这个问题——通过引入rest参数(剩余参数),你可以接收任意数量的参数。这就好比一个能装任意食材的无底洞口袋。
function makeSalad(...ingredients) { return `Making a salad with ingredients: ${ingredients.join(', ')}.` } console.log(makeSalad('lettuce', 'tomato', 'cucumber')) // Making a salad with ingredients: lettuce, tomato, cucumber.
剩余参数必须放到最后一个位置,否则会报错:
function foo(m, ...args, n) { console.log(m, args, n) } // Rest parameter must be last formal parameter foo(20, 30, 40, 50)
那么剩余参数和arguments有什么区别呢?
- 剩余参数只包含那些没有对应形参的实参,而 arguments 对象包含了传给函数的所有实参
- arguments对象不是一个真正的数组,而rest参数是一个真正的数组,可以进行数组的所有操作
- arguments是早期的ECMAScript中为了方便去获取所有的参数提供的一个数据结构,而rest参数是ES6中提供并且希望以此来替代arguments的
三、拓展运算符
展开语法(Spread syntax):
- 可以在函数调用/数组构造时,将数组表达式或者string在语法层面展开
- 还可以在构造字面量对象时, 将对象表达式按key-value的方式展开
在函数调用时使用:
const names = ['a','b','c','d'] foo(...names) const name = "abc" foo(...name)
在数组构造时使用:
const newNames = [...names, ...name] console.log(newNames)
在构建对象字面量时,也可以使用展开运算符,这个是在ES2018(ES9)中添加的新特性:
const newObj = {...obj, height: 1.88, ...names} console.log(newObj)
展开语法是一种浅拷贝:
const obj = { friend: { name: "kobe" } } const newObj = { ...obj } newObj.friend.name = "james" console.log(obj.friend.name) // james
四、对象与数组的解构赋值
ES6中新增了一个从数组或对象中方便获取数据的方法,称之为解构Destructuring。
4.1. 数组的解构
数组的解构就是从数组中获取我们需要的数组:
var names = ["abc", "cba", "nba"] var [name1, name2, name3] = names console.log(name1, name2, name3)
数组的解构必须按照数据的顺序依次获取,如果我们只想获取第二个和第三个,那么可以有如下语法:
var [, nameb, namec] = names console.log(nameb, namec)
如果我们希望解构出来一个元素,其他元素继续放到另外一个数组中:
var [namea, ...newNames] = names console.log(namea, newNames)
如果我们解构的数据数量大于数组中原本的数据数量,那么会返回undefined:
var [namex, namey, namez, namem] = names console.log(namem) // undefined
我们可以在解构出来的数据为undefined的时候,给它一个默认值:
var [namex, namey, namez, namem = "aaa"] = names console.log(namem) // aaa
4.2. 对象的解构
对象的解构和数组的解构是相似的,不同之处在于:
- 数组中的元素是按照顺序排列的,并且我们只能根据顺序来确定需要获取的数据
- 对象中的数据由key和value组成,我们可以通过key来获取想要的value
var obj = { name: "why", age: 18, height: 1.88 } var { name, age, height } = obj console.log(name, age, height)
因为对象是可以通过key来解构的,所以它对顺序、个数都没有要求:
var { height, name, age } = obj console.log(name, age, height) var { age, height } = obj console.log(age, height)
如果我们对变量的名称不是很满意,那么我们可以重新命名:
var { name: whyName, age: whyAge } = obj console.log(whyName, whyAge)
我们也可以给变量一个默认值:
var { name, address = "广州市" } = obj console.log(name, address)
4.3. 解构的使用
- 在开发中拿到一个变量时,自动对其进行解构使用
- 对函数的参数进行解构