ES6标准

let与var

let 关键字声明变量时,其作用域仅限于该代码块、语句或表达式。
var 关键字声明变量时,它是全局声明的,如果在函数内部声明则是局部声明的。

let 暂时性死区

利用let声明的变量会绑定在这个块级作用域,不会受外界的影响

 var tmp = 123;
 if (true) { 
     tmp = 'abc';
     let tmp; 
 } 

var与let的经典面试题

 var arr = [];
 for (var i = 0; i < 2; i++) {
     arr[i] = function () {
         console.log(i); 
     }
 }
 arr[0]();  //2
 arr[1]();  //2

解: 此题的关键点在于变量i是全局的,函数执行时输出的都是全局作用域下的i值。

 let arr = [];
 for (let i = 0; i < 2; i++) {
     arr[i] = function () {
         console.log(i); 
     }
 }
 arr[0](); //0
 arr[1](); //1

解: 此题的关键点在于每次循环都会产生一个块级作用域,每个块级作用域中的变量都是不同的,函数执行时输出的是自己上一级(循环产生的块级作用域)作用域下的i值.

const

  • 具有块级作用域
  • 声明常量,常量名全部大写
const s = [5, 6, 7];
s = [1, 2, 3];  //出错,不能使用赋值运算符
s[2] = 45;  //可以

-Object.freeze(变量)
const声明的常量依旧可以被改变
为了确保数据不被改变,JavaScript 提供了一个函数 Object.freeze()

let obj = {
  name:"FreeCodeCamp",
  review:"Awesome"
};
Object.freeze(obj);

箭头函数

  1. 没有参数的
const myFunc = () => {
  const myVar = "value";
  return myVar;
}

当不需要函数体,只返回一个值的时候,箭头函数允许你省略 return 关键字和外面的大括号。

const myFunc = () => "value";
  1. 有参数
const doubler = (item) => item * 2;
doubler(4);
  1. 有默认参数
const greeting = (name = "Anonymous") => "Hello " + name;

this

  • 箭头函数中不绑定this,箭头函数中的this指向是它所定义的位置,可以简单理解成,定义箭头函数中的作用域的this指向谁,它就指向谁
  • 箭头函数的优点在于解决了this执行环境所造成的一些问题。比如:解决了匿名函数this指向的问题(匿名函数的执行环境具有全局性),包括setTimeout和setInterval中使用this所造成的问题
const obj = { name: '张三'} 
function fn () { 
    console.log(this);//this 指向 是obj对象
    return () => { 
        console.log(this);//obj
        //this 指向的是箭头函数定义的位置,那么这个箭头函数定义在fn里面
        //而这个fn指向是的obj对象,所以这个this也指向是obj对象
    } 
} 
const resFn = fn.call(obj); 
resFn()

关于箭头函数中的this的经典面试题

var age = 100;

var obj = {
	age: 20,
	say: () => {
		alert(this.age)
	}
}

obj.say();//100
//箭头函数this指向的是被声明的作用域里面,而对象没有作用域的,所以箭头函数虽然在对象中被定义,但是this指向的是全局作用域

rest操作符(…)接受若干个参数

剩余参数语法允许我们将一个不定数量的参数表示为一个数组,不定参数定义方式,这种方式很方便的去声明不知道参数情况下的一个函数

const sum = (...args) => {
  return args.reduce((a, b) => a + b, 0);
}
//sum()   0
//sum(0,1,2) 3
//sum(4,5)  9

function sum (first, ...args) {
     console.log(first); // 10
     console.log(args); // [20, 30] 
 }
sum(10, 20, 30)

解构赋值

中允许从数组中提取值,按照对应位置,对变量赋值,对象也可以实现解构

获取对象的值

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

//ES5
const name = user.name;
const age = user.age;
//ES6 解构赋值
const { name, age } = user;

从对象中分配变量

const user = { name: 'John Doe', age: 34 };
//userName是user中的name的新赋值的变量名
const { name: userName, age: userAge } = user;

从嵌套对象中分配变量

const user = {
  johnDoe: { 
    age: 34,
    email: 'johnDoe@freeCodeCamp.com'
  }
};

//解构对象的属性值赋值给具有相同名字的变量
const { johnDoe: { age, email }} = user;
//将对象的属性值赋值给具有不同名字的变量
const { johnDoe: { age: userAge, email: userEmail }} = user;

从数组中分配变量

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

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

配合 rest 操作符来重新分配数组元素

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

将对象作为函数的参数传递

//ES5
const profileUpdate = (profileData) => {
  const { name, age, nationality, location } = profileData;
}

//ES6
const profileUpdate = ({ name, age, nationality, location }) => {
}
//当 profileData 被传递到上面的函数时,从函数参数中解构出值以在函数内使用。

Array 的扩展方法(★★)

展开操作符

…arr 返回一个解压的数组。 但展开操作符只能够在函数的参数中或者数组中使用。

//直接复制数组
const arr1 = ['JAN', 'FEB', 'MAR', 'APR', 'MAY'];
let arr2 = [...arr1]; 

//找出一个数组中最大的数
const arr = [6, 89, 3, 45];
const maximus = Math.max(...arr); 
//或
var arr = [6, 89, 3, 45];
var maximus = Math.max.apply(null, arr); 

//合并数组
let ary1 = [1, 2, 3];
let ary2 = [3, 4, 5];
let ary3 = [...ary1, ...ary2];
ary1.push(...ary2);

//将类数组或可遍历对象转换为真正的数组
let oDivs = document.getElementsByTagName('div'); 
oDivs = [...oDivs];

Math.max(arr); //报错
const spreaded = ...arr; //报错

构造函数方法:Array.from()

将伪数组或可遍历对象转换为真正的数组

//定义一个集合
let arrayLike = {
    '0': 'a',
    '1': 'b',
    '2': 'c',
    length: 3
}; 
//转成数组
let arr2 = Array.from(arrayLike); // ['a', 'b', 'c']

方法还可以接受第二个参数,作用类似于数组的map方法,用来对每个元素进行处理,将处理后的值放入返回的数组

 let arrayLike = { 
     "0": 1,
     "1": 2,
     "length": 2
 }
 let newAry = Array.from(arrayLike, item => item *2)//[2,4]

注意:如果是对象,那么属性需要写对应的索引

实例方法:find()

用于找出第一个符合条件的数组成员,如果没有找到返回undefined

let ary = [{
     id: 1,
     name: '张三'
 }, { 
     id: 2,
     name: '李四'
 }]; 
 let target = ary.find((item, index) => item.id == 2);//找数组里面符合条件的值,当数组中元素id等于2的查找出来,注意,只会匹配第一个

实例方法:findIndex()

用于找出第一个符合条件的数组成员的位置,如果没有找到返回-1

let ary = [1, 5, 10, 15];
let index = ary.findIndex((value, index) => value > 9); 
console.log(index); // 2

实例方法:includes()

判断某个数组是否包含给定的值,返回布尔值。

[1, 2, 3].includes(2) // true 
[1, 2, 3].includes(4) // false

String 的扩展方法

模板字面量创建字符串

const person = {
  name: "Zodiac Hasbro",
  age: 56
};

//注意:使用的是``反引号,而不是单引号
//其次,多行也无需换行符
//再者,使用${variable}占位符,而不是+连接符号了
const greeting = `Hello, my name is ${person.name}!
I am ${person.age} years old.`;

console.log(greeting);
//Hello, my name is Zodiac Hasbro! 
//I am 56 years old.

//在模板字符串中可以调用函数
const sayHello = function () { 
    return '哈哈哈哈 追不到我吧 我就是这么强大';
}; 
let greet = `${sayHello()} 哈哈哈哈`;
console.log(greet); // 哈哈哈哈 追不到我吧 我就是这么强大 哈哈哈哈

例子: 使用模板字符串和表达式内插的方法令返回的数组为

[
  '<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 item of arr){
    failureItems.push(`<li class="text-warning">${item}</li>`);
  }
  // 只修改这一行上面的代码
  return failureItems;
}

const failuresList = makeList(result.failure);

实例方法:startsWith() 和 endsWith()

  • startsWith():表示参数字符串是否在原字符串的头部,返回布尔值
  • endsWith():表示参数字符串是否在原字符串的尾部,返回布尔值
let str = 'Hello world!';
str.startsWith('Hello') // true 
str.endsWith('!')       // true

实例方法:repeat()

repeat方法表示将原字符串重复n次,返回一个新字符串

'x'.repeat(3)      // "xxx" 
'hello'.repeat(2)  // "hellohello"

Set 数据结构(★★)

ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。

Set本身是一个构造函数,用来生成 Set 数据结构

const s = new Set();

Set函数可以接受一个数组作为参数,用来初始化。

const set = new Set([1, 2, 3, 4, 4]);//{1, 2, 3, 4}

实例方法(add、delete、has、clear)

  • add(value):添加某个值,返回 Set 结构本身
  • delete(value):删除某个值,返回一个布尔值,表示删除是否成功
  • has(value):返回一个布尔值,表示该值是否为 Set 的成员
  • clear():清除所有成员,没有返回值
 const s = new Set();
 s.add(1).add(2).add(3); // 向 set 结构中添加值 
 s.delete(2)             // 删除 set 结构中的2值   
 s.has(1)                // 表示 set 结构中是否有1这个值 返回布尔值 
 s.clear()               // 清除 set 结构中的所有值
 //注意:删除的是元素的值,不是代表的索引

遍历

Set 结构的实例与数组一样,也拥有forEach方法,用于对每个成员执行某种操作,没有返回值。

s.forEach(value => console.log(value))

```## 编写简洁的对象字面量声明

```javascript
//原:
const getMousePosition = (x, y) => ({
  x: x,
  y: y
});

//ES6:消除了类似 x: x 这种冗余的写法
const getMousePosition = (x, y) => ({ x, y });

编写简洁的函数声明

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

//ES6:删除 function 关键词和冒号
const person = {
  name: "Taylor",
  sayHello() {
    return `Hello! My name is ${this.name}.`;
  }
};

class 语法定义构造函数

在 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');

getter 和 setter 来控制对象的访问

Getter 函数的作用是可以让对象返回一个私有变量,而不需要直接去访问私有变量。
Setter 函数的作用是可以基于传进的参数来修改对象中私有变量。 这些修改可以是计算,或者是直接替换之前的值。

class Book {
  constructor(author) {
    //通常会在私有变量前添加下划线(_)。 然而,这种做法本身并不是将变量变成私有的。
    this._author = author;
  }
  // getter
  get writer() {
    return this._author;
  }
  // setter
  set writer(updatedAuthor) {
    this._author = updatedAuthor;
  }
}
const novel = new Book('anonymous');
console.log(novel.writer);
novel.writer = 'newAuthor';
console.log(novel.writer);

创建一个模块脚本

<html>
  <body>
    <!-- 只修改这一行下面的代码 -->
    <script type="module" src="index.js"></script>
    <!-- 只修改这一行上面的代码 -->
  </body>
</html>

export 来重用代码块

假设有一个文件 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 };

import 复用 JavaScript 代码

import 可以导入文件或模块的一部分。

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

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

用 * 从文件中导入所有内容

import * as myMathModule from "./math_functions.js";

上面的 import 语句会创建一个叫作 myMathModule 的对象。 这只是一个变量名,可以随便命名。 对象包含 math_functions.js 文件里的所有导出,可以像访问对象的属性那样访问里面的函数。 下面是使用导入的 add 和 subtract 函数的例子:

myMathModule.add(2,3);
myMathModule.subtract(5,3);

export default 默认导出

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

//命名函数
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 文件的任何默认导出值。 在导入默认导出时,可以使用任何名字。

Promise

Promise 是异步编程的一种解决方案 - 它在未来的某时会生成一个值。当程序需要花费未知的时间才能完成时(比如一些异步操作),一般是服务器请求,promise就很有用。 任务完成,分执行成功和执行失败两种情况。 Promise 是构造器函数,需要通过 new 关键字来创建。 构造器参数是一个函数,该函数有两个参数 - resolve 和 reject。 通过它们来判断 promise 的执行结果。
Promise 有三个状态:pending、fulfilled 和 rejected。Promise 提供的 resolve 和 reject 参数就是用来结束 promise 的。 Promise 成功时调用 resolve,promise 执行失败时调用 reject。
当promise发起请求后,服务器请求会花费一些时间,当结束时,需要根据服务器的响应执行一些操作。 这可以用 then 方法来实现。当 promise 完成 resolve 时会触发 then 方法。
当 promise 失败时会调用 catch 方法。 当 promise 的 reject 方法执行时会直接调用。

const myPromise = new Promise((resolve, reject) => {
  if(condition here) {
    resolve("Promise was fulfilled");
  } else {
    reject("Promise was rejected");
  }
});

myPromise.then(result => {

});

myPromise.catch(error => {

});
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值