Understanding ECMAScript6(上)

2017-02-16  本文已影响0人  Michael_lpf


引言

写下这一系列关于 ES6 笔记要从《Understanding ECMA6》 这本书说起。
我在网上找到了 中译版,拜读了一下(对译者感激不尽!)。
读过了书当然要整理一下知识,于是就有了这篇笔记。

先看 Scott 老师的大宝剑🗡,简单阐述了 ES6 的实用新特性👇


Paste_Image.png

我们慢慢道来。。。


Part 1: 块级绑定(块级作用域)


const 声明
Paste_Image.png Paste_Image.png
let 声明和“暂时性死区”
Paste_Image.png

JS 引擎面对 var 声明会将其提升至顶,而面对 const 和 let 则会将其置于“暂时性死区”,在死区内访问变量都会导致错误。上面第3、4行代码不会执行的。
但若在块外访问变量,则只会返回一个可能和预期不一样的结果而已,不至于报错。

Paste_Image.png
循环内的函数
Paste_Image.png

这是因为循环内对 i 的引用是共享的,意味着循环内定义的函数是对同一个变量(循环结束时的值)的引用。
我们使用立即执行函数修复这个问题👇

Paste_Image.png

如今使用 let 声明循环中的变量可以达到同样的效果,更简洁👇

Paste_Image.png

这是因为每次循环,都创建一个变量绑定,每个函数拥有了变量的副本,于是输出不同的值。


不添加属性到全局对象

let 和 const 声明全局变量/常量时,并非会在全局对象上添加属性,这与 var 声明完全不同👇

Paste_Image.png
块级作用域最佳实践


Part 2: 函数


参数默认值
Paste_Image.png

只有当参数未传递👇


Paste_Image.png

或是指定参数为 undefined 时👇

Paste_Image.png

默认参数值才会被使用。


参数默认值对 arguments 对象的影响

在 ES5 非严格模式下,arguments 对象会更新自己以反映参数的变化👇

Paste_Image.png

在 ES5 严格模式下,为打消混乱,arguments 对象不再更新👇

Paste_Image.png

在使用了 ES6 默认参数值的函数中,arguments 对象的表现和严格模式下的表现一致(无论是否声明了严格模式)👇

Paste_Image.png

(👆上面例子中第二个 console.log 输出 false,是因为调用是没有传入参数 b,此时 b 为 2,arguments[1] 为 undefined。)
至此,我们也就可用 arguments 来了解参数的初始状态了。


参数默认值表达式
function foo(first, second = first){
  return first + second
}

如此,调用时可以只传一个实参了foo(1) //2,乍看没什么生产用途。
不急,还可以将前面的参数传递给一个函数来产生后面的参数👇

function increase(val){
  return val + 5;
}
function foo(first, second = increase(first)){
  return first + second
}
foo(1);  //  7

剩余参数
Paste_Image.png Paste_Image.png

一个返回第一个剩余参数的例子👇

Paste_Image.png
箭头函数
var foo = val => val;
//  等同于
var foo = function(val){
  return val;
}

当函数多于一个参数,需要圆括号将参数括起来👇

var add = (a, b) => a + b;
//  等同于
var add = function(a, b){
  return a + b;
}

若函数没有参数,那么必须使用一对空圆括号👇

var foo = () => true;
//  等同于
var foo = function(){
  return true;
}

当函数包含多个语句时,需要花括号括起来,并明确 return 👇

var cal = (a, b) => { a++; return a + b}
//  等同于
var cal = function(a, b){
  a++
  return a + b;
}

如果函数内需要返回对象字面量,则需要用圆括号括起来👇

var getObj = () => ({ name:'Nick', age:30});
//  等同于
var getObj = function(){
  return {
    name:'Nick',
    age:30
  }
}
//  一个立即调用函数
var person1 = (function(name){
  return {
    getName: function(){
      return name
    }
  }
})('Nick');
//  另一个立即调用函数
var person2 = (function(name){
  return {
    getName: function(){
      return name;
    }
  }
}('Penny'));

但使用箭头函数时,圆括号只需包裹函数体,不要包裹 “参数调用” 部分👇

let person3 = ((name) => {
  return {
    getName: function(){
      return name;
    }
  }
})('Marvin');
Paste_Image.png

Part 3: 扩展的对象功能


属性速记和方法简写
//  ES5
function person(name, age){
  return {
    name: name,
    age: age
  }
}
//  ES6 属性速记
function person(name, age){
  return {
    name,
    age
  }
}

当只有属性名时,JS 引擎会查找周边作用域中同名的变量,若找到,改变量的值会赋给同名属性。

//  ES5
var personA = {
  name: 'Noviziki',
  getName: function(){
    console.log(this.name);
  }
}
//  ES6简写
var personB = {
  name: 'Ragger',
  gerName(){
    console.log(this.name);
  }
}

重复的对象字面量属性

在 ES5 严格模式中,重复定义的对象属性是会造成语法错误的。
在 ES6 中不再对其检查,无论是否声明严格模式。

Paste_Image.png

👆 同名属性后者的值会覆盖前者。


明确的对象属性枚举顺序

ES5 没有明确的对象属性枚举顺序,各 JS 引擎厂商未必统一。
ES6 中对此作了定义:数字键总是在前,以升序排列;之后分别是字符串和符号键按添加顺序排列。

Paste_Image.png
修改对象的原型
Paste_Image.png Paste_Image.png

Part 4: 解构:方便的数据访问


对象解构

在 ES5 中从对象中取值👇

Paste_Image.png

ES6 解构语法👇

Paste_Image.png

使用结构器,必须初始化,否则有语法错误👇

Paste_Image.png

也可以先声明,后解构赋值。
但要将表达式写在一个圆括号中(避免被 JS 引擎解析为代码块)👇

Paste_Image.png

当变量没有在对象中找到同名属性的时候,无意外,它会被赋值 undefined👇

Paste_Image.png

当然也可以在解构中使用默认值,就像函数的参数默认值一样👇

Paste_Image.png

一定要将本地变量和对象属性名设置成一样的吗?这样不够灵活。当然不是👇

Paste_Image.png

👆不过这里的语法有些新颖,与传统对象字面量语法相反。
被赋值的本地变量书写在冒号之后,而真正的值(此处是对象属性值)则书写在冒号之前。

嵌套的对象结构:
嵌套的对象结构适用于层级深一些的对象。

Paste_Image.png
数组解构

与对象解构非常相似,只是不存在同名、不同名的对接方法。
赋值的顺序由原数组顺序决定👇

Paste_Image.png

可以有意忽略若干项,使用 , 来占位👇

Paste_Image.png

同样可以有默认值👇

Paste_Image.png

同样可以先声明,后解构赋值。
而且不必将表达式写在圆括号中👇

Paste_Image.png

嵌套的数组解构,使用 [] 下潜到数组深层👇

Paste_Image.png

剩余项,和函数的参数剩余项又很类似,使用 ... 接收数组解构赋值的剩余项目👇

Paste_Image.png

数组剩余项解构在生产中有个很常用的技巧:克隆数组。

Paste_Image.png

本节完
Understanding ECMAScript6(中)
Understanding ECMAScript6(下)

上一篇 下一篇

猜你喜欢

热点阅读