ES2015学习笔记(1)——简单概念
2019-06-30 本文已影响1人
全栈顾问
和ES5有对应关系的几个增强特性,包括:变量和常量;解构赋值;for...of迭代;增强对象字面量;箭头函数;参数缺省值;剩余参数;展开语法。
可在本地环境中直接用NodeJs执行。
局部变量(Let+Const)
let
声明一个块范围的局部变量。
function varTest() {
var x = 1
if (true) {
var x = 2 // same variable!
console.log(x) // 2
}
console.log(x) // 2
}
function letTest() {
let x = 1
if (true) {
let x = 2 // different variable
console.log(x) // 2
}
console.log(x) // 1
}
varTest()
letTest()
- let声明的变量通过this访问不到。
- let声明的变量不能重复声明。
- let声明的变量必须定义后再使用。
const
的作用域和let
的作用域相同,声明时必须指定值。
参考:MDN let statement,MDN const statement
解构赋值(Destructuring)
解构赋值语法是一种 Javascript 表达式。通过解构赋值,可以将属性/值从对象/数组中取出,赋值给其他变量。
解构数组
var a, b, rest
;[a, b] = [10, 20]
console.log(a) // expected output: 10
console.log(b) // expected output: 20
;[a, b, ...rest] = [10, 20, 30, 40, 50]
console.log(rest) // expected output: [30,40,50]
// 忽略某些返回值
function f() {
return [1, 2, 3]
}
var [a, , b] = f()
console.log(a) // 1
console.log(b) // 3
// 将剩余数组赋值给一个变量
var [a, ...b] = [1, 2, 3]
console.log(a) // 1
console.log(b) // [2, 3]
解构对象
var o = { p: 42, q: true }
var { p, q } = o
console.log(p) // 42
console.log(q) // true
// 给新的变量名赋值
var o = { p: 42, q: true }
var { p: foo, q: bar } = o
console.log(foo) // 42
console.log(bar) // true
// 默认值
var { a = 10, b = 5 } = { a: 3 }
console.log(a) // 3
console.log(b) // 5
// 对象属性计算名和解构
let key = "z"
let { [key]: foo } = { z: "bar" }
console.log(foo) // "bar"
// 对象解构中的 Rest
let { a, b, ...rest } = { a: 10, b: 20, c: 30, d: 40 }
a // 10
b // 20
rest // { c: 30, d: 40 }
迭代(Iterators + For...Of)
for..of
迭代访问可迭代对象。
let iterable = [10, 20, 30];
for (let value of iterable) {
value += 1;
console.log(value);
}
// 11
// 21
// 31
for...in
访问对象的所有可枚举属性(enumerable),且不保证顺序。for...of
只能可迭代对象定义的可迭代数据。
Object.prototype.objCustom = function() {};
Array.prototype.arrCustom = function() {};
let iterable = [3, 5, 7];
iterable.foo = 'hello';
// 返回的是可枚举属性
for (let i in iterable) {
console.log(i); // logs 0, 1, 2, "foo", "arrCustom", "objCustom"
}
for (let i in iterable) {
if (iterable.hasOwnProperty(i)) {
console.log(i); // logs 0, 1, 2, "foo"
}
}
// 可迭代的值
for (let i of iterable) {
console.log(i); // logs 3, 5, 7
}
参考:MDN for...of
增强对象字面量(Enhanced Object Literals)
var theProtoObj = { p1: "a" }
var handler = function() {}
var prop1 = 1
var obj = {
// __proto__
__proto__: theProtoObj,
// Shorthand for ‘prop1: prop1’
prop1,
// Shorthand for ‘handler: handler’
handler,
// Methods
toString() {
// Super calls
return "d " + super.toString()
},
// Computed (dynamic) property names
["prop_" + (() => 42)()]: 42
}
for (let i in obj) {
console.log(i)
}
// output:
// prop1
// handler
// toString
// prop_42
// p1
- 和属性名同名的定义可以简写(handler)
箭头函数(Arrows)
// Expression bodies
const evens = [2, 4, 6, 8, 10]
var odds = evens.map(v => v + 1)
var nums = evens.map((v, i) => v + i)
// 返回的是对象,必须用小括号括起来
var pairs = evens.map(v => ({ even: v, odd: v + 1 }))
console.log("odds", odds) // output: odds [ 3, 5, 7, 9, 11 ]
console.log("nums", nums) // output: nums [ 2, 5, 8, 11, 14 ]
console.log("pairs", pairs)
// output:
// pairs [ { even: 2, odd: 3 },
// { even: 4, odd: 5 },
// { even: 6, odd: 7 },
// { even: 8, odd: 9 },
// { even: 10, odd: 11 } ]
// Statement bodies
var fives = []
nums.forEach(v => {
if (v % 5 === 0) fives.push(v)
})
console.log("fives", fives) // output: fives [ 5 ]
// Lexical this
var bob = {
_name: "Bob",
_friends: ["Alice"],
printFriends() {
this._friends.forEach(f => console.log(this._name + " knows " + f))
}
}
bob.printFriends() // output: Bob knows Alice
// 返回字面量对象必须用括号括起来
fn = n => ({ foo: n })
console.log(fn(1)) // output: { foo: 1 }
- 函数体内的
this
对象,就是定义时所在的对象,而不是使用时所在的对象。 - 如果要是返回对象,需要用小括号括起来。
- 不支持
arguments
。 - 不能用
new
,不能作为构造函数。 - 箭头函数体分为精简(concise)和块(block)两种模式,精简模式是一个表达式,并返回(不用写reture);块模式必须用reture指定返回结果。如果返回的是对象字面量,必须用括号括起来(
() => ({ foo: 1 })
)。 - 箭头和括考之间不允许有断行。
参考: MDN 箭头函数
参数默认值(Default)
function multiply(a, b = 1) {
return a * b
}
console.log(multiply(5, 2)) // 10
console.log(multiply(5)) // 5
// 传入undefined时默认值生效
function test(num = 1) {
console.log(typeof num)
}
test() // 'number' (num is set to 1)
test(undefined) // 'number' (num is set to 1 too)
// test with other falsy values:
test("") // 'string' (num is set to '')
test(null) // 'object' (num is set to null)
// 默认值在调用时评估
function append(value, array = []) {
array.push(value)
return array
}
// 参数列表从左到右评估
console.log(append(1)) //[1]
console.log(append(2)) //[2], not [1, 2]
function greet(name, greeting, message = greeting + " " + name) {
return [name, greeting, message]
}
console.log(greet("David", "Hi")) // ["David", "Hi", "Hi David"]
console.log(greet("David", "Hi", "Happy Birthday!")) // ["David", "Hi", "Happy Birthday!"]
- 传入
undefined
,默认值生效。 - 默认值是在调用时进行评估(重新赋值)。
- 参数列表从左到右评估。
剩余参数(Rest)
function sum(...x) {
return x.reduce((previous, current) => previous + current)
}
console.log(sum(1, 2, 3)) // expected output: 6
console.log(sum(1, 2, 3, 4)) // expected output: 10
-
arguments
不是数组,rest parameters
是数组。
参考:MDN 剩余参数
展开语法(Spread)
function sum(x, y, z) {
return x + y + z
}
const numbers = [1, 2, 3]
console.log(sum(...numbers))
// expected output: 6
console.log(sum.apply(null, numbers))
// expected output: 6
// 用于new
var dateFields = [1970, 0, 1] // 1970年1月1日
var d = new Date(...dateFields)
console.log(d)
// 数组拷贝
var arr = [1, 2, 3]
var arr2 = [...arr] // like arr.slice()
arr2.push(4)
console.log(arr2)
// arr2 此时变成 [1, 2, 3, 4]
// arr 不受影响
// 连接多个数组
var arr1 = [0, 1, 2]
var arr2 = [3, 4, 5]
var arr3 = [...arr1, ...arr2]
console.log(arr3)
// 构造字面量对象时使用展开语法
var obj1 = { foo: "bar", x: 42 }
var obj2 = { foo: "baz", y: 13 }
var clonedObj = { ...obj1 }
// 克隆后的对象: { foo: "bar", x: 42 }
console.log(clonedObj)
var mergedObj = { ...obj1, ...obj2 }
// 合并后的对象: { foo: "baz", x: 42, y: 13 }
console.log(mergedObj)
参考:MDN 展开语法