hercule_poirt
^

ES6学习笔记

ES6笔记(javaScript语言的最新标准)

1. var和let关键字之间的差异

  • let(块级作用域)
    用来声明局部变量,只在let命令所在的代码块内有效.

  • Var(函数作用域和全局作用域)
    只有函数作用域和全局作用域,没有块级作用域.
    没有块级作用域意味着: {}限定不了var声明变量的访问范围
    特点:

    注意:使用 var 关键字来声明变量,会出现重复声明导致变量被覆盖却不会报错的问题.

var camper = 'James';
var camper = 'David';
//本应是再赋值,但var再声明又再赋值,是错误却不会报错
console.log(camper);
后果:
在大项目中,因为不会报错,会导致搜索和修复 bug 会变得非常困难.
以及在循环中使用var命名的多个变量return传回会导致错误的值


解决办法①

使用let来代替var:
因为使用let进行重复的声明会导致报错.

解决办法②
使用 "use strict" 指令:
"use strict" 不是一条语句,但是是一个字面量表达式在 JavaScript 旧版本中会被忽略.
"use strict" 的目的是指定代码在严格条件下执行, 这代表着开启了严格模式

严格模式下你不能使用未声明的变量

"use strict";
x = 3.14;// 这将显示一个错误 x is not defined.

2. 用const关键字声明只读变量

let 并不是唯一的新的声明变量的方式.
在 ES6 里面,你还可以使用 const 关键字来声明变量.

Const(变量不可变,对象|数组|函数仍然可变)
具有let的所有优点,但是const 声明的变量是只读的, 这意味着通过 const 声明的变量只能被赋值一次,不可再赋值.

对象(包括数组和函数)在使用 const 声明的时候依然是可变的.

3. 重点js语法规则


  • 通常用大写字母作为常量标识符

  • 用小写字母或者驼峰命名作为变量(对象或数组)标识符

    不能再赋值变量,但是能改变对象|数组|函数的原理:

    指针原理,例中s[2]是指向对象中的元素,是可以改变的.
    但是,s=[1,2,3]是指向了另一个对象,这是不允许的.

    你不能使用赋值操作符将变量标识 s 指向另外一个数组.
    不能通过=再赋值,但是可以通过指向具体的元素进而改变.

const s = [5, 6, 7];
s = [1, 2, 3];
s[2] = 45;
console.log(s);



  • ${variable}语法是一个占位符。 这样一来,你将不再需要使用 + 运算符来连接字符串。
  • 反引号(`)和引号(' 或者 ")一样,也能将字符串括起来
const person = {
  name: "Zodiac Hasbro",
  age: 56
};
const greeting = `Hello, my name is ${person.name}!
I am ${person.age} years old.`;
console.log(greeting);

如下输出了指定列表

[
  '<li class="text-warning">no-var</li>',
  '<li class="text-warning">var-on-top</li>',
  '<li class="text-warning">linebreak</li>'
]
const result = {
  success: ["max-length", "no-amd", "prefer-arrow-functions"],
  failure: ["no-var", "var-on-top", "linebreak"],
  skipped: ["no-extra-semi", "no-dup-keys"]
};
function makeList(arr) {
  // 只修改这一行下面的代码
  const failureItems =[];
  for (let i=0;i< arr.length;i++){
  failureItems[i] = `<li class="text-warning">${arr[i]}</li>`;
  };
  console.log(failureItems);
  // 只修改这一行上面的代码
  return failureItems;
}
const failuresList = makeList(result.failure);

结论: Const声明并不能完全的保护数据不被改变.

完全的保护数据
Object.freeze
当一个对象被冻结的时候,你不能再对它的属性再进行增、删、改的操作. 任何试图改变对象的操作都会被阻止,且不会报错.

4. 使用箭头函数编写简洁的匿名函数

适用于不需要给函数命名的情况, 如将一个函数作为参数传给另外一个函数的时候.
箭头函数允许你省略 return 关键字和外面的大括号.

//(参数) =>{执行语句}
//(参数) =>() 相当于直接返回括号中内容
const myFunc = function(){
/*函数构造器New的匿名函数版本*/
  const myVar = "value";
  return myVar;
}//原函数
const myFunc = () => "value";//使用箭头的匿名函数

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

使用箭头函数传递参数

const doubler = (item) => item * 2;
doubler(4);// 只有一个参数时,可以省略参数外面的括号
const doubler = item => item * 2;

如果箭头函数只有一个参数,则可以省略参数外面的括号.
设置函数的默认参数

const greeting = (name = "Anonymous") => "Hello " + name;
console.log(greeting());

默认参数会在参数没有被指定(值为 undefined)的时候起作用.

5. rest操作符(不同于展开运算符)

(将把逗号隔开的值|序列组合成一个数组)

rest运算符即三个点…

function howMany(...args) {
  return "You have passed " + args.length + " arguments.";
}
console.log(howMany(0, 1, 2));
console.log(howMany("string", null, [1, 2, 3], { }));

使用 rest 参数,就不需要查看 args 数组,
并且允许我们在参数数组上使用 map()、filter() 和 reduce().

const sum = (...args) => args.reduce((a, b) => a + b, 0);

可以接收任意数量的参数

6. spread展开操作符(展开操作符可以提升代码的可读性)

可以展开数组以及需要多个参数或元素的表达式

const arr1 = ['JAN', 'FEB', 'MAR', 'APR', 'MAY'];
let arr2;
arr2 = [...arr1];  // 修改这一行
console.log(arr2);

通过展开操作符将 arr1 中的内容都复制到 arr2 中去。

7. 解构赋值(从数组和对象中快速的提取值)

7.1 提取值
const user = { name: 'John Doe', age: 34 };
const name = user.name;
const age = user.age;//没有解构赋值语句只能参数赋值.
const { name, age } = user;//通过结构语句提取参数

注意,结构语句会自动创建 name 和 age 变量,不需要再单独声明.

7.2 赋值给新变量
const { name: userName, age: userAge } = user;

此处获取 user.name 的值,将它赋给一个新的变量 userName.

7.3 从嵌套对象中赋值给新变量

相应的解构语句也要使用对象中的数组{}.

const user = {
  johnDoe: {
    age: 34,
    email: 'johnDoe@freeCodeCamp.com'
  }
};
const { johnDoe: {
age: userAge, email: userEmail }} = user;//解构赋值
7.4从数组中分配变量(,分隔符)

通过在数组解构中使用逗号分隔符,来获取任意一个想要的值:

const [a, b,,, c] = [1, 2, 3, 4, 5, 6];
console.log(a, b, c);//输出为1,2,5

同样的也可以来交换值,例中使用数组解构来交换变量 a 与 b 的值.

let a = 8, b = 6;
[b,a]=[a,b];
7.5 在数组中与rest操作符配合

因为 rest 操作符的存在,arr 获取了除开前两个元素的的原数组剩余的元素的值

const source = [1,2,3,4,5,6,7,8,9,10];
function removeFirstTwo(list) {
  const [,,...arr] = list; // 修改这一行
  return arr;
}
const arr = removeFirstTwo(source);
7.6 在对象中使用解构赋值传参
const profileUpdate = (profileData) => {
const { name, age, nationality, location } = profileData;
}//未使用解构赋值
const profileUpdate = ({ name, age, nationality, location }) => {}//使用了解构赋值,不需要创建profileData

8. 简洁的对象字面量声明

getMousePosition 简单的函数,返回拥有两个属性的对象。

const createPerson = (name, age, gender) => ({name,age,gender});
//输出:
{name: "Zodiac Hasbro", age: 56, gender: "male"}

通过使用简单字段的写法,消除了类似 x: x 这种冗余的写法。

9. 简洁的函数声明

用 ES6 的语法在对象中定义函数的时候,可以删除 function 关键词和冒号。

const person = {
  name: "Taylor",
  sayHello()/*:function()*/{
    return `Hello! My name is ${this.name}.`;
  }
};

10. 使用 class 语法定义构造函数

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

var SpaceShuttle = function(targetPlanet){
this.targetPlanet = targetPlanet;
};
class SpaceShuttle { constructor(targetPlanet) {
    this.targetPlanet = targetPlanet;
  }
};//class替换后

应该注意 class 关键字声明了一个新的函数
constructor 方法是一个特殊方法,用于创建和初始化 class 创建的对象。

11. 使用 getter 和 setter 来控制对象的访问

getter 和 setter 非常重要,因为它们隐藏了内部的实现细节。

注意: 通常会在私有变量前添加下划线(_)。 然而,这种做法本身并不是将变量变成私有的。

class Book {
  constructor(author) {
    this._author = author;
}
  // getter
  get writer() {
    return this._author;//返回_author值
  }
  // setter
  set writer(updatedAuthor) {
    this._author = updatedAuthor;//更新_author值
  }
}
const novel = new Book('anonymous');
console.log(novel.writer);
novel.writer = 'newAuthor';
console.log(novel.writer);

控制台将显示字符串 anonymous 和 newAuthor。

12. 模块化脚本(跨js文件共享代码)

ES6 引入了在多个 JavaScript 文件之间共享代码的机制。
它可以导出文件的一部分供其它文件使用,然后在需要它的地方按需导入。

为了使用这一功能, 需要在 HTML 文档里创建一个 type 为 module 的脚本。 例子如下:

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

(使用了 module 类型的脚本可以使用 import 和 export 特性)

12.1 使用export来导出代码块

将函数导出当前文件,从而实现跨文件调用函数.

export const add = (x, y) => {
  return x + y;
}//导出单个函数或对象
export { add };//导出单个函数或对象
export { add, subtract };//导出多个函数或对象
12.2 使用import来导入代码块

在使用export导出函数|对象后,还需要使用import导入函数|对象.

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

./ 告诉程序在当前文件的相同目录寻找 math_functions.js 文件.
同样的,多个项目也可以一起导入.

import { add, subtract } from './math_functions.js';
12.3 使用import * as来导入所有代码块

例中为从同目录下的 math_functions.js 文件中导入所有内容

import * as myMathModule from "./math_functions.js";
12.4使用默认导出/导入

用export default创建一个默认导出
在文件中只有一个值需要导出的时候,通常会使用这种语法。

export default function add(x, y) {
  return x + y;
}//默认导出命名函数
export default function(x, y) {
  return x + y;
}//默认导出匿名函数

export default 用于为模块或文件声明一个返回值
注意:你不能将 export default 与 var、let 或 const 同时使用。
导入【默认导出】

import add from "./math_functions.js";

重点:add 值没有被花括号({})所包围。
add 只是一个变量的名字,对应 math_functions.js 文件的任何默认导出值。 在导入默认导出时,可以使用任何名字。

13 构造器函数(需要通过 new 关键字来创建)

13.1 构造器函数Promise

Promise 是异步编程的一种解决方案,它在未来的某时会生成一个值。分执行成功和执行失败两种情况。
构造器参数是一个函数,该函数有两个参数 - resolve 和 reject。 通过它们来判断 promise 的执行结果。

const myPromise = new Promise((resolve, reject) => {
});
13.2 Promise 的三个状态
  • Pending(未发生)

  • fulfilled(已发生)

  • rejected(拒绝)

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");
  }
});

上面的示例使用字符串作为这些函数的参数,但参数实际上可以是任何格式。
通常,它可能是一个包含数据的对象,你可以将它放在网站或其他地方。

13.3 用 then 处理 Promise 完成的情况

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

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

  if(responseFromServer) {
    resolve("We got the data");
  } else {
    reject("Data not received");
  }
});
makeServerRequest.then(result => {
  console.log(result);
});

通过给promise 添加 then 方法。用 result 做为回调函数的参数并将 result 打印在控制台。

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

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

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

error 是传入 reject 方法的参数。

posted @ 2021-10-09 20:08  hercule_poirt  阅读(66)  评论(0)    收藏  举报
Copyright © 2021 hercule_poirt