JavaScript 进阶营你不知道的JavaScript让前端飞

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()

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

参考:对象字面量(Object literals)

箭头函数(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 }

参考: 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!"]

参考:Default parameters

剩余参数(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

参考: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 展开语法

上一篇下一篇

猜你喜欢

热点阅读