二、 ES6

2.1 let, var, const定义变量

  • var: 定义变量如果是在函数内部的是局部,外面就是全局的
  • let: 定义的变量是局部使用的,无法替换跨域
  • const: 常量定义,无法被改变,但可以单独改变内部变量,比如字符串修改 s[2] = ‘a’;
    • const 声明并不会真的保护数据不被改变。 为了确保数据不被改变,JavaScript 提供了一个函数 Object.freeze(变量)

2.2 匿名函数

我们通常会使用以下语法:

const myFunc = function() {
  const myVar = "value";
  return myVar;
}

ES6 提供了其他写匿名函数的方式的语法糖。 你可以使用箭头函数:

const myFunc = () => {
  const myVar = "value";
  return myVar;
}

当不需要函数体,只返回一个值的时候,箭头函数允许你省略 return 关键字和外面的大括号。 这样就可以将一个简单的函数简化成一个单行语句。

const myFunc = () => "value";

这段代码默认会返回字符串 value。

同时可以通过括号里面的变量进行传参:

const mul = (a, b=2) => a*b;
console.log(mul(5));
const product = (n1, n2, n3) => {
  const args = [n1, n2, n3];
  return args.reduce((a, b) => a * b, 1);
}
console.log(product(2, 4, 6)); //48
// 简化:
const product = (...n) => {
  return n.reduce((a, b) => a * b, 1);
}
console.log(product(2, 4, 6)); //48

展开函数 变量前用 三个点:

const arr1 = [1,2,3,4];
const arr2 = [...arr1];

使用 解构赋值 来获取对象的值:


const user = { username: 'John Doe', age: 34 };

const name = user.username;
const age = user.age;

// 简化
const { username:name, age } = user;

// 也可以嵌套


// 使用解构赋值从数组中分配变量
let a = 8, b = 6;
// 只修改这一行下面的代码
[a, b] = [b,a]; // 交换a,b的值

//
const [a, b, ...arr] = [1, 2, 3, 4, 5, 7]; // arr = [3, 4, 5, 7]

2.3 使用 class 语法定义构造函数

ES6 提供了一个新的创建对象的语法,使用关键字 class。 值得注意的是,class 只是一个语法糖,它并不像 Java、Python 或者 Ruby 这一类的语言一样,严格履行了面向对象的开发规范。 在 ES5 里面,我们通常会定义一个构造函数 constructor,然后使用 new 关键字来实例化一个对象:

var SpaceShuttle = function(targetPlanet){
  this.targetPlanet = targetPlanet;
}
var zeus = new SpaceShuttle('Jupiter');


// class 语法只是简单地替换了构造函数 constructor 的写法:

class SpaceShuttle {
  constructor(targetPlanet) {
    this.targetPlanet = targetPlanet;
  }
}
const zeus = new SpaceShuttle('Jupiter');

应该注意 class 关键字声明了一个新的函数,里面添加了一个构造函数。 当用 new 创建一个新的对象时,构造函数会被调用。

2.4 用 export 来重用代码块

如果要引用外部模块可以通过调用script完成:

<script type="module" src="index.js"></script>

假设有一个文件 math_functions.js,该文件包含了数学运算相关的一些函数。 其中一个存储在变量 add 里,该函数接受两个数字作为参数返回它们的和。 你想在几个不同的 JavaScript 文件中使用这个函数。 要实现这个目的,就需要 export 它。

export const add = (x, y) => { return x + y; } 上面是导出单个函数常用方法,还可以这样导出:

const add = (x, y) => { return x + y; }

export { add }; 导出变量和函数后,就可以在其它文件里导入使用从而避免了代码冗余。 重复第一个例子的代码可以导出多个对象或函数,在第二个例子里面的导出语句中添加更多值也可以导出多项,例子如下:

export { add, subtract };

如果是在js文件中引用其他外部文件的方法,可以适用import的方式

import 可以导入文件或模块的一部分。 在之前的课程里,例子从 math_functions.js 文件里导出了 add。 下面看一下如何在其它文件导入它:

import { add } from ‘./math_functions.js’; 在这里,import 会在 math_functions.js 里找到 add,只导入这个函数,忽略剩余的部分。 ./ 告诉程序在当前文件的相同目录寻找 math_functions.js 文件。 用这种方式导入时,相对路径(./)和文件扩展名(.js)都是必需的。

通过在 import 语句里添加项目,可以从文件里导入多个项目,如下:

import { add, subtract } from './math_functions.js';

// 用 * 从文件中导入所有内容
import * as myMathModule from "./math_functions.js";

用 export default 创建一个默认导出(在文件中只有一个值需要导出的时候,通常会使用这种语法。 它也常常用于给文件或者模块创建返回值):

// 命名函数
export default function add(x, y) {
  return x + y;
}

//匿名函数。
export default function(x, y) {
  return x + y;
}

导入一个默认的导出: import add from “./math_functions.js”;

2.5 JavaScript Promise

Promise 是异步编程的一种解决方案 - 它在未来的某时会生成一个值。 任务完成,分执行成功和执行失败两种情况。 Promise 是构造器函数,需要通过 new 关键字来创建。 构造器参数是一个函数,该函数有两个参数 - resolve 和 reject。 通过它们来判断 promise 的执行结果。 用法如下:

const myPromise = new Promise((resolve, reject) => {

});

Promise 有三个状态:pending、fulfilled 和 rejected。 上一个挑战里创建的 promise 一直阻塞在 pending 状态里,因为没有调用 promise 的完成方法。 Promise 提供的 resolve 和 reject 参数就是用来结束 promise 的。 Promise 成功时调用 resolve,promise 执行失败时调用 reject, 如下文所述,这些方法需要有一个参数。

const myPromise = new Promise((resolve, reject) => { if(condition here) { resolve(“Promise was fulfilled”); } else { reject(“Promise was rejected”); } }); 上面的示例使用字符串作为这些函数的参数,但参数实际上可以是任何格式。 通常,它可能是一个包含数据的对象,你可以将它放在网站或其他地方。

当程序需要花费未知的时间才能完成时(比如一些异步操作),一般是服务器请求,promise 很有用。 服务器请求会花费一些时间,当结束时,需要根据服务器的响应执行一些操作。 这可以用 then 方法来实现, 当 promise 完成 resolve 时会触发 then 方法。 例子如下:

myPromise.then(result => {

}); result 即传入 resolve 方法的参数。下面例子 给 promise 添加 then 方法。 用 result 做为回调函数的参数并将 result 打印在控制台。

const makeServerRequest = new Promise((resolve, reject) => {
  // responseFromServer 设置为 true,表示从服务器获得有效响应
  let responseFromServer = true;

  if(responseFromServer) {
    resolve("We got the data");
  } else {  
    reject("Data not received");
  }
});

makeServerRequest.then(result => {
  console.log(result);
});

makeServerRequest.catch(error=>{
  console.log(error);
});

使用 catch 处理 Promise 失败的情况:

当 promise 失败时会调用 catch 方法。 当 promise 的 reject 方法执行时会直接调用。 用法如下:

myPromise.catch(error => {

});

error 是传入 reject 方法的参数。