ES6语法学习笔记

let和const
  • let:声明变量,只在let所在作用域内有效,在声明变量之前,该变量都不能使用,被称为暂时性死区。
  • letconst没有变量提升
  • let不允许在相同的作用域内重复声明同一个变量
  • const:声明的值不得改变,const一旦声明变量就必须立即初始化,不能留到以后赋值const:实质是保证变量指向的内存地址所保存的数据不能改动。
  • 顶层对象,浏览器中指window,node中指global
模板字符串
  • 模板字符串用反引号标识:``
  • 可以使用${} 添加变量,{}中也可以是函数,表达式
变量的解构赋值
  • 解构赋值的规则:只要等号右边的值不是对象或数组,就会先将其转换为对象。数组的解构赋值
  • 模式匹配:等号两边的模式相同,左边的变量就会被赋予右边的对应的值。解构不成功时,会被赋值为
    undefined
  • 默认值:解构赋值允许有默认值,所以要,只有===undefined时,默认值才能生效
对象的解构赋值
  • 属性名字匹配:变量名与属性名相同时才能取到正确的值,解构不成功,被赋值为undefined 对象的解构赋值是将前者的值解构赋予后者:
let { foo: baz } = { foo: 'aaa', bar: 'bbb' };
baz // "aaa"
foo // error: foo is not defined
字符串解构赋值
  • 字符串的解构赋值是默认将字符串转换为类数组对象了数值与布尔值的解构赋值
  • 如果等号右边的值是数值和布尔值,那么会先转换为对象,再进行解构赋值。
对象字面量
  • ES6允许在对象之中,直接写变量。属性可以简写,如:
function f(x, y) {
  return {x, y};
}

// 等同于

function f(x, y) {
  return {x: x, y: y};
}

f(1, 2) // Object {x: 1, y: 2}
  • 方法也可以简写,省略function:
const o = {
  method() {
    return "Hello!";
  }
};

// 等同于

const o = {
  method: function() {
    return "Hello!";
  }
};
  • ES6允许字面量定义对象时,用表达式作为对象的属性名,但是要将表达式放在方括号内
let lastWord = 'last word';

const a = {
  'first word': 'hello',
  [lastWord]: 'world'
};

a['first word'] // "hello"
a[lastWord] // "world"
a['last word'] // "world"
  • 表达式也可以用于定义方法名
let obj = {
  ['h' + 'ello']() {
    return 'hi';
  }
};

obj.hello() // hi
箭头函数
  • ES6允许使用“箭头”(=>)定义函数,箭头函数可以省略function关键字
var f = v => v;

// 等同于
var f = function (v) {
  return v;
};
  • 如果箭头函数没有参数或者有多个参数,就需要使用圆括号,如果只有一个参数,可以将圆括号省略
var f = () => 5;
// 等同于
var f = function () { return 5 };

var sum = (num1, num2) => num1 + num2;
// 等同于
var sum = function(num1, num2) {
  return num1 + num2;
};
  • 箭头函数的this指针指向的是定义时所在的对象,而不是使用时所在的对象
  • 箭头函数不可以当作构造函数,不可以使用new命令
  • 不可以使用arguments对象,该对象在函数体内不存在。可以使用rest参数代替
Import和Export
  • ES6的模块自动采用严格模式,不管有没有在模块头部添加‘use strict’
  • 严格模式的限制有:
    • 变量必须声明后使用
    • 函数的参数不能有同名的属性不能对只读属性赋值
    • 禁止this指向全局对象,ES6中顶层的this指向undefined
export命令
  • 模块的功能主要由两个命令构成:exportimport
  • export用于规定模块的对外接口,import命令用于输入其他模块提供的功能 如果你需要在外部读取到模块内部的某个变量,就必须使用export输出该变量
export var firstName = 'Michael';
export var lastName = 'Jackson';
export var year = 1958;

// 等同于
var firstName = 'Michael';
var lastName = 'Jackson';
var year = 1958;
export { firstName, lastName, year };
  • export除了输出变量,还可以输出函数或类(class)
export function multiply(x, y) {
  return x * y;
};
  • 通常情况下,export输出的变量就是本来的名字,但是可以使用as关键字重命名
function v1() { ... }
function v2() { ... }

export {
  v1 as streamV1,
  v2 as streamV2,
  v2 as streamLatestVersion
};
//  重命名后v2可以以不同的名字输出两次
  • export命令规定的是对外的接口,必须与模块内部的变量建立一一对应的关系
import命令
  • 使用export定义了模块的对接口以后,就可以通过import命令来加载这个模块了
import { firstName, lastName, year } from './profile.js';
  • import命令接受一对大括号,里面指定要从其他模块导入的变量名。大括号里面的变量名必须与被导入模块对 外接口的名称相同。import后面的from指定模块的文件位置,可以是相对位置,也可以是绝对位置。
  • 如果想要重新命名,可以使用as关键字
import { lastName as surname } from './profile.js';
  • import 命令输入的变量都是只读的,不允许在加载模块的脚本里面,改写接口。但是可以改写接口的属性。
  • import是静态执行,所以不能使用表达式变量。
export default命令
  • export default就是输出一个default的变量或者方法,在import输入的时候允许为他命名为任意的名字。
  • 一个模块只能有一个默认输出,因此export default命令只能使用一次。所以,import命令后不需要加{},因为只能唯一对应到export default的值
// modules.js
function add(x, y) {
  return x * y;
}
export {add as default};
// 等同于
// export default add;

// app.js
import { default as foo } from 'modules';
// 等同于
// import foo from 'modules';
  • export default 命令其实是输出一个叫做default的值,所以他的后面不能跟变量声明的语句
// 正确
export var a = 1;

// 正确
var a = 1;
export default a;

// 错误
export default var a = 1;
装饰器
  • 修饰作用于类,
  • 修饰器函数的第一个参数是要修饰的目标类。修饰器可以接受参数,相当于修改修饰器
function testable(isTestable) {
  return function(target) {
    target.isTestable = isTestable;
  }
}

@testable(true)
class MyTestableClass {}
MyTestableClass.isTestable // true

@testable(false)
class MyClass {}
MyClass.isTestable // false
  • 修饰器对类的行为改变,是代码编译时发生的。意味着修饰器能在编译阶段运行代码。 修饰器的本质就是编译时执行的函数
  • 修饰器修饰类的属性
  • 修饰器的第一个参数是类的原型对象,第二个参数是所要修饰的属性名,第三个参数是该属性的描述对象
class Person {
  @readonly
  name() { return `${this.first} ${this.last}` }
}

function readonly(target, name, descriptor){
  // descriptor对象原来的值如下
  // {
  //   value: specifiedFunction,
  //   enumerable: false,
  //   configurable: true,
  //   writable: true
  // };
  descriptor.writable = false;
  return descriptor;
}

readonly(Person.prototype, 'name', descriptor);
// 类似于
Object.defineProperty(Person.prototype, 'name', descriptor);
  • 修饰器不能作用于函数的原因是:函数存在变量提升,导致函数实际执行顺序与书写的不一致
Promise
  • promise对象的两个特点
    • 对象的状态不受外界影响。promise有三种状态,pending(进行中)、fufilled(已成功)、rejected(已失败)。只有异步操作的结果可以决定当前的状态。
    • 一旦状态改变,就不会再改变,任何时候都可以得到这个结果。promise对象的状态改变只有两种可能: 从pending变为fufilled和从pending变成rejected
  • promise的基本用法:
const promise = new Promise(function(resolve, reject) {
  // ... some code

  if (/* 异步操作成功 */){
    resolve(value);
  } else {
    reject(error);
  }
});
  • promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolvereject
  • resolve函数作用是将promise对象的状态变为成功,并将异步操作的结果作为参数传递出去。
  • reject函数 的作用是将promise的状态变为失败,并将异步操作的错误作为参数传递出去。
  • promise实例生成后,可以使用then方法来分别指定resolved状态和rejected状态的回调。
promise.then(function(value) {
  // success
}, function(error) {
  // failure
});
  • promise新建后就会立即执行,then函数会进入异步队列等候执行
  • Promise.prototype.then()
    • then方法定义在原先对象promise.prototype上。作用是为promise实例添加状态改变时的回调函数
    • then方法的第一个参数是resolved状态的回调函数,第二个参数(可选)是rejected状态的回调函数。 then方法的返回值是一个新的promise实例,因此可以采用链式写法,在then方法后再调用另一个then方 法。
getJSON("/posts.json").then(function(json) {
  return json.post;
}).then(function(post) {
  // ...
});
  • promise.prototype.catch()
    • Promise.prototype.catch方法是.then(null, rejection).then(undefined, rejection)的别名,用于指定发生错误时的回调函数。
getJSON('/posts.json').then(function(posts) {
  // ...
}).catch(function(error) {
  // 处理 getJSON 和 前一个回调函数运行时发生的错误
  console.log('发生错误!', error);
});
  • 如果没有使用catch方法指定错误处理的回调函数,promise对象抛出的错误就不会传递到外层代码。
    因此建议在promise对象后面要跟catch方法,catch方法返回的也是一个promise对象,接着还可以调用
    then方法。promise.prototype.finally()
  • finally方法用于指定不管promise对象最后状态如何,都会执行的操作。
promise
.then(result => {···})
.catch(error => {···})
.finally(() => {···});
 // 不管promise最后的状态,在执行完then或catch指定的回调函数以后,都会执行finally方法指定的回调函数。
  • finally方法的回调不接受任何参数,也就是无法指定promise的状态是成功还是失败。finally里面的操作是 与状态无关的,不依赖promise的状态。
  • promise.all()
    promise.all方法用于将多个promise实例,包装成一个新的promise实例。
const p = Promise.all([p1, p2, p3]);
  // Promise.all方法接受一个数组作为参数,p1、p2、p3都是 Promise 实例
  // p的状态由p1、p2、p3决定,分成两种情况。
  // 只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled

如果作为参数的promise实例,自己定义了catch方法,那么他被rejected之后也不会触发promise.all
catch方法

const p1 = new Promise((resolve, reject) => {
  resolve('hello');
})
.then(result => result)
.catch(e => e);

const p2 = new Promise((resolve, reject) => {
  throw new Error('报错了');
})
.then(result => result)
.catch(e => e);

Promise.all([p1, p2])
.then(result => console.log(result))
.catch(e => console.log(e));
// ["hello", Error: 报错了]

// p1会resolved,p2首先会rejected,但是p2有自己的catch方法,该方法返回的是一个新的 Promise 实例,p2指向的实际上是这个实例。该实例执行完catch方法后,也会变成resolved,导致Promise.all()方法参数里面的两个实例都会resolved,因此会调用then方法指定的回调函数,而不会调用catch方法指定的回调函数。
// 如果p2没有自己的catch方法,就会调用Promise.all()的catch方法。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342