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方法。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值