最新消息: USBMI致力于为网友们分享Windows、安卓、IOS等主流手机系统相关的资讯以及评测、同时提供相关教程、应用、软件下载等服务。

ES6 B站学习笔记

互联网 admin 9浏览 0评论

ES6 B站学习笔记

文章目录

    • 1. ES6
      • let
          • 经典题目,for循环
      • const
      • 解构赋值
        • 数组解构
        • 对象解构
      • 箭头函数
      • 剩余参数
        • 数组解构与剩余参数使用
      • ES6内置扩展方法
        • 扩展运算符
        • Array的扩展方法
          • Array.from() 将伪数组转化为数组
          • find()
          • findIndex()
          • includes()
        • String的扩展方法
          • 模板字符串
          • startsWith() endsWith()
          • repeat()
      • Set 数据结构
      • Map数据结构
      • ES6对象简化写法
      • ES6允许给参数赋值初始值
      • Symbol
        • Symbol内置值
      • 迭代器
        • 自定义迭代器
      • 生成器
        • 生成器函数实例
      • Promise
        • then方法
        • 链式调用(then里面的函数可以回promise对象)
        • catch方法
      • 对象扩展方法
        • Object.is
        • Object.assign
        • Object.setPrototypeOf 设置原型对象
        • Object.getPrototypeOf获取原型对象
      • async与await
        • async
        • await
        • async和await合作读取文件

1. ES6

let

  • let声明的变量只在所处于的块级别有效
  • 不存在变量提升(就是不能先使用再声明)
  • 暂时性死区:一旦块级作用域定义了这个变量,外面定义的变量和这个变量就没关系了
var num = 10;
if(true){console.log(num); // num not definedlet num = 20;
}var num = 10;if(true){let num = 20;console.log(num); // => 20}
  • 不影响作用域链
{let school = 'school';function fn() {console.log(school);  // => 'school'}fn();
}
经典题目,for循环
// 变量i是全局的,函数执行时输出的都是全局作用域下的i值。var arr = [];for (var i = 0; i < 2; i++) {arr[i] = function () {console.log(i); }}arr[0](); // 2arr[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

const

  • 声明常量,常量就是值(内存地址)不能变化的量

  • const也具有块级作用域

  • 声明必须赋初始值

  • 复杂数据类型(对象数组)内部值可以更改,比如数组arr[0] = 1是允许的

解构赋值

数组解构

let ary = [1, 2 ,3];
let [a, b, c, d, e] = ary;
console.log(a); // 1
console.log(b); // 2
console.log(c); // 3
console.log(d); // undefined
console.log(e); // undefined

对象解构

  • 对象解构允许我们使用变量的名字匹配对象的属性,匹配成功就将对象的属性的值赋值给变量
let person = {name: 'andy', age: 18, sex: '男'};
let {name, age, sex} = person;
console.log(name); // 'andy'
console.log(age); // 18
console.log(sex); // '男'
let person = {name: 'andy', age: 18, sex: '男'};
let {name: myName} = person;
//  用name匹配person的name再把值赋值给myName,name只用于匹配,myName才是真正变量
console.log(myName); // 'andy'

箭头函数

  • 箭头函数是用来简化函数定义的
  • 如果函数体只有一句代码,并且代码的执行结构就是函数的返回值,那么大括号可以省略
const sum = (a, b) => n1 + n2;
const result = sum(10, 20);
console.log(result); // => 30 
  • 形参只有一个就可以省略
const fn = v => {alert(v);
}; 
fn(20);
  • 箭头函数不绑定this 没有自己的this关键字,如果在箭头函数里面使用this,指向箭头函数定义位置(声明时所在作用域下 this 的值)中的this
function fn() {console.log(this);return () => {console.log(this);}
}const obj = {name: 'zhangsan'};
const resFn = fn.call(obj);
resFn(); // => obj obj
var obj = {age: 20,say: () => {alert(this.age);}
}obj.say(); // undefined
//对象中不存在作用域,所以say实际上是被定义在window,但是window没有age属性

剩余参数

  • ES5获取剩余参数的方式
function data() {console.log(arguments);  
}
data('a', 'b', 'c');  // => Arguments(3) ["a", "b", "c", callee: ƒ, Symbol(Symbol.iterator): ƒ]
  • 剩余参数语法允许我们将不定数量的参数作为实参
const sum = (...args) => {let total = 0;args.forEach(item => total += item);return total;
};
console.log(sum(10, 20)); // 30
cossole.log(sum(10, 20, 30)); // 60

数组解构与剩余参数使用

let ary1 = ['a', 'b', 'c'];
let [s1, ...s2] = ary1;
console.log(s1); // 'a'
console.log(s2); // ['b', 'c']

ES6内置扩展方法

扩展运算符

  • 扩展运算符可以将数组或者对象转为用 , 分隔的参数序列
let ary = [1, 2, 3];
console.log(...ary); // 1 2 3
console.log(1, 2, 3); // 1 2 3
// 两种等价,扩展运算符可以将数组或者对象转为用 , 分隔的参数序列,...ary等同于 1,2,3,再打印就没有逗号了
  • 合并数组
// method 1
let ary1 = [1, 2, 3];
let ary2 = [4, 5, 6];
let ary3 = [...ary1, ...ary2];// method 2
ary1.push(.ary2);
  • 利用扩展运算符将伪数组转换为真数组
var divs = document.getElementsByTagName('div');
var ary = [...divs];
// 就可以调用数组的api了

Array的扩展方法

Array.from() 将伪数组转化为数组
  • 方法还可以接受第二个参数,作用类似于数组的map方法,用来对每个元素进行处理,将处理后的值放入返回的数组。
var arrayLike = {"0": "1","1": "2","length": 2
}var ary = Array.from(arrayLike, item => item * 2)
console.log(ary) // => (2) [2, 4]
find()
  • 用于找出第一个符合条件的数组成员,如果没有找到返回undefined
var ary = [{id: 1,name: '张三'
}, {id: 2,name: '李四'
}];
let target = ary.find(item => item.id == 3);
console.log(target) // => undefined
findIndex()
  • 用于找出第一个符合条件的数组成员的位置,如果没有找到返回-1
let ary = [10, 20, 50];
let index = ary.findIndex(item => item > 15);
console.log(index) // => 1
includes()
  • 表示某个数组是否包含给定的值,返回布尔值。
let ary = ["a", "b", "c"];let result = ary.includes('a')
console.log(result) // => true
result = ary.includes('e')
console.log(result) // => false

String的扩展方法

模板字符串
  • ES6新增的创建字符串的方式,使用反引号定义
let name = `这是一个模板字符串`;
console.log(name); // => '这是一个模板字符串'
  • 模板字符串可以解析变量
let name = `张三`;
let sayHello = `hello, my name is ${name}`;
console.log(sayHello); // => hello, my name is 张三
  • 模板字符串可以换行
let result = {name: 'zhangsan',age: 20
};let html = `
<div><span>${result.name}</span>
</div>
`
console.log(html);
/*
<div><span>zhangsan</span>
</div>
*/
  • 在模板字符串中可以调用函数
const fn = () => {return '我是fn函数'
}
let html = `我是模板字符串${fn()}`;
console.log(html) // => 我是模板字符串我是fn函数
startsWith() endsWith()
  • startsWith():表示参数字符串是否在原字符串的头部,返回布尔值
  • endsWith(): 表示参数字符是否在原字符串的尾部,返回布尔值
let str = 'hello es6';
let r1 = str.startsWith('hello');
console.log(r1); // true
let r2 = str.endsWith('es6');
console.log(r2); // false
repeat()
  • 将原字符串重复n次,返回新字符串
console.log('xy'.repeat(2)); // xyxy

Set 数据结构

  • 类似数组,但是成员唯一
  • Set本身是一个构造函数,用来生产Set数据结构
const s = new Set();
console.log(s.size); // 0
  • Set函数可以接受一个数组作为参数来初始化
const set = new Set([1, 2, 3, 4]);
console.log(set.size); //4
  • 用set来去重
const s3 = new Set([1, 2, 3, 3]);
console.log(s3.size); // => 3
const ary = [...s3];
console.log(ary); // => [1, 2, 3]
  • add(value):添加某个值,返回set本身
  • delete(value):删除某个值,返回一个布尔值,表示删除是否成功
  • has(value):返回一个布尔值,表示该值是否为set成员
  • clear():清楚所有成员,没有返回值
  • foreach遍历

Map数据结构

  • ES6 提供了 Map 数据结构。它类似于对象,也是键值对的集合。但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。Map 也实现了iterator 接口,所以可以使用『扩展运算符』和『for…of…』进行遍历。Map 的属性和方法:
    • size 返回 Map 的元素个数
    • set 增加一个新元素,返回当前 Map
    • get 返回键名对象的键值
    • has 检测 Map 中是否包含某个元素,返回 boolean 值
    • clear 清空集合,返回 undefined
  //声明 Maplet m = new Map();//添加元素m.set('name', 'xiaoming');m.set('change', function () {console.log("change");});let key = {school: 'ATGUIGU'};m.set(key, ['北京', '上海', '深圳']);//sizeconsole.log(m.size);//删除m.delete('name');//获取console.log(m.get('change'));//清空m.clear();//遍历for (let v of m) {console.log(v);}

ES6对象简化写法

let name = 'aaa';
let improve = function () {console.log('improve');
}//属性和方法简写
let atguigu = {name,improve,change() { // change: function(){}console.log('change')}
};

ES6允许给参数赋值初始值

function add (a, b, c = 10) {return a + b + c;
}
let result = add(1, 2);
console.log(result); // => 13
  • 与解构赋值结合
function connect({host = '127.0.0.1', username, password, port}) { // 127.0.0.1默认值 //log host username password port
}connect({host: 'localhost',username: 'root',password: 'root',port: 3306
})

Symbol

ES6 引入了一种新的原始数据类型 Symbol,表示独一无二的值。它是JavaScript 语言的第七种数据类型,是一种类似于字符串的数据类型。

  • 用Synmbol创建的值不能与其他数据进行运算
  • 创建Symbol
let s = Symbol();
console.log(s, typeof f);
let s2 = Symbol('a');
let s2_2 = Symbol('a');
console.log(s2 === s2_2); // false//使用 Symbol for 定义
let s3 = Symbol.for('a');
let s3_2 = Symbol.for('a');
console.log(s3 === s3_2); // true

Symbol内置值

Symbol.hasInstance当其他对象使用 instanceof 运算符,判断是否为该对象的实例时,会调用这个方法
Symbol.isConcatSpreadable对象的 Symbol.isConcatSpreadable 属性等于的是一个布尔值,表示该对象用于 Array.prototype.concat()时,是否可以展开。
Symbol.species创建衍生对象时,会使用该属性
Symbol.match当执行 str.match(myObject) 时,如果该属性存在,会调用它,返回该方法的返回值。
Symbol.replace当该对象被 str.replace(myObject)方法调用时,会返回该方法的返回值。
Symbol.search当该对象被 str. search (myObject)方法调用时,会返回该方法的返回值。
Symbol.split当该对象被 str. split (myObject)方法调用时,会返回该方法的返回值。
Symbol.iterator对象进行 for…of 循环时,会调用 Symbol.iterator 方法,返回该对象的默认遍历器
Symbol.toPrimitive该对象被转为原始类型的值时,会调用这个方法,返回该对象对应的原始类型值。
Symbol. toStringTag在该对象上面调用 toString 方法时,返回该方法的返回值
Symbol. unscopables该对象指定了使用 with 关键字时,哪些属性会被 with环境排除。
class Person {static[Symbol.hasInstance](param) {console.log(param);console.log("被检测了");return false;}
}let o = {};
console.log(o instanceof Person); 
// => {} 被检测了 false 

迭代器

遍历器(Iterator)就是一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作。

  1. ES6 创造了一种新的遍历命令 for…of 循环,Iterator 接口主要供 for…of 消费

  2. 原生具备 iterator 接口的数据(可用 for of 遍历)

a) Array

b) Arguments

c) Set

d) Map

e) String

f) TypedArray

g) NodeList

const xiyou = ['tangseng', 'sunwukong', 'zhubajie', 'shaseng'];
for(let v of xiyou) {console.log(v); // 'tangseng' 'sunwukong' 'zhubajie' 'shaseng'
} 

自定义迭代器

  • 用for of 自定义遍历对象中的某个数组
let banji = {name: '一班',stus: ['xiaoming','xiaoning','xiaotian','knight'],[Symbol.iterator]() {let index = 0;let that = this;return {next: function() {if(index < that.stus.length) {index++;return {vlaue: that.stus[i], done: false};} else {return {value: undefined, done: true};}}};}
}for(let v of banji) {console.log(v); // 'xiaoming' 'xiaoning' 'xiaotian' 'knight'
}

生成器

生成器函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同

  • 生成器函数返回的结果是迭代器对象,调用迭代器对象的 next 方法可以得到yield语句后的值
  • yield 相当于函数的暂停标记,也可以认为是函数的分隔符,每调用一次 next方法,执行一段代码
function * gen(){yield '一只没有耳朵';yield '一只没有尾巴';return '真奇怪';
}let iterator = gen();
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
/*
{value: "一只没有耳朵", done: false}
{value: "一只没有尾巴", done: false}
{value: "真奇怪", done: true}
{value: undefined, done: true}
*/
  • next 方法可以传递实参,作为 yield 语句的返回值
function * gen(){let one = yield 111;console.log(one);yield 222;
}
let iterator = gen();
console.log(iterator.next()); // {value: 111, done: false} 
console.log(iterator.next('BBB')); // 'BBB' {value: 222, done: false} 

生成器函数实例

  • 场景:先获取用户名,一秒后再获取用户订单,一秒后再获取用户订单里的商品
function getUsers() {setTimeout(() => {let data = 'userData';iterator.next(data);}, 1000)
}
function getOrders() {setTimeout(() => {let data = 'orderData';iterator.next(data);}, 1000)
}
function getGoods() {setTimeout(() => {let data = 'goodsData';iterator.next(data);}, 1000)
}function * gen() {let users = yield getUsers();console.log(users);let orders = yield getOrders();console.log(orders);let goods = yield getGoods();console.log(goods);
}let iterator = gen();
iterator.next(); // userData (1s) orderData (1s) goodsData

Promise

  • Promise 是 ES6 引入的异步编程的新解决方案。语法上 Promise 是一个构造函数,用来封装异步操作并可以获取其成功或失败的结果。

  • Promise 构造函数: Promise (excutor) {}

  • Promise.prototype.then 方法

  • Promise.prototype.catch 方法

  • 实例化Promise

const p = new Promise(function(resolve, reject) {setTimeout(function() {//let data = 'data';//resolve(data);let err = 'err';reject(err);}, 1000)
});p.then(function(value) {console.log(value);
}, function(reason) {console.log(reason);
}) // => reason
// 当setTimeout里面的函数调用resolve的时候,p的状态变为success,p.then调用第一个回调函数
// 当setTimeout里面的函数调用reject的时候,p的状态变为fail,p.then调用第二个回调函数
  • 用Promise封装文件读取
const fs = require('fs');fs.readFile('./resources/为学.md', (err, data) => {if (err) throw err;console.log(data.toString());
});// --------------------------封装-------------------------------------------
const p = new Promise((resolve, reject) => {fs.readFile('./resources/为学.mda', (err, data) => {if(err) reject(err);resolve(data);})
});p.then(value => {console.log(value.toString());
}, reason => {console.log(reason);
})
  • 用Promise封装AJAX
  // 创建const xhr = new XMLHttpRequest();// 初始化xhr.open("GET", "/getJoke");// 发送xhr.send();// 绑定事件xhr.onreadystatechange = function () {if (xhr.readyState === 4) {if (xhr.status >= 200 && xhr.status < 300) {console.log(xhr.response); // => ...} else {console.log(xhr.status);}}}// --------------------------------封装--------------------------------------const p = new Promise((resolve, reject) => {// 创建const xhr = new XMLHttpRequest();// 初始化xhr.open("GET", "/getoke");// 发送xhr.send();// 绑定事件xhr.onreadystatechange = function () {if (xhr.readyState === 4) {if (xhr.status >= 200 && xhr.status < 300) {resolve(xhr.response);} else {reject(xhr.status);}}}});p.then(value => {console.log(value);}, reason => {console.error(reason);   //404})

then方法

  • 调用then方法返回的结果是Promise对象
const p = new Promise((resolve, reject) => {setTimeout(() => {resolve('data');}, 1000)
});const result = p.then(value => {console.log(value);return 'aaa';
}, reason => {console.warn(reason);
});console.log(result);
/*
Promise {<pending>}
__proto__: Promise
[[PromiseState]]: "fulfilled"
[[PromiseResult]]: "aaa"'data'
*/

链式调用(then里面的函数可以回promise对象)

const p = new Promise((resolve, reject) => {setTimeout(() => {resolve('data');}, 1000)
});p.then(value => {return new Promise((resolve, reject) => {resolve('ok');// reject('no');})
}).then(value => {})
  • 链式调用demo
const fs = require("fs");const p = new Promise((resolve, reject) => {fs.readFile('./resources/为学.md', (err, data) => {if(err) reject(err);resolve(data);})
});p.then(value => {console.log(value.toString());return new Promise((resolve, reject) => {fs.readFile('./resources/插秧诗.md', (err, data) => {if(err) reject(err);resolve(data);})})
}, reason => {console.error(reason);
}).then(value => {console.log(value.toString());return new Promise((resolve, reject) => {fs.readFile('./resources/观书有感.md', (err, data) => {if(err) reject(err);resolve(data);})})
}, reason => {console.error(reason);
}).then(value => {console.log(value.toString());
}, reason => {console.error(reason);
})

catch方法

  • Promise.prototype.catch方法是.then(null,rejection)的别名,用于指定发生错误时的回调函数,算是语法糖
p.then((val) => console.log('fulfilled:', val)).catch((err) => console.log('rejected', err));// 等同于
p.then((val) => console.log('fulfilled:', val)).then(null, (err) => console.log("rejected:", err));

对象扩展方法

Object.is

  • 判断两个值是否完全相等
console.log(Object.is(120, 120)); // true
console.log(Object.is(NaN, NaN)); // true
console.log(NaN, NaN) // false

Object.assign

  • 对象的合并

  • 都有后面把前面覆盖,前有后没有保留,后没有前有省去

const o1 = {host: 'loacalhost',port: 3306,test: 'test'
}
const o2 = {host: '',port: 33060,test2: 'test2'
}console.log(Object.assign(o1, o2));
/*
{    host: '',port: 33060,test: 'test'
}
*/

Object.setPrototypeOf 设置原型对象

Object.getPrototypeOf获取原型对象

const school = {name: 'xiaoming'
}
const cities = {city: ['beijing', 'shanghai']
}
Object.setPrototypeOf(school, cities);
console.log(school); // school原型是cities
console.log(Object.getPrototypeOf(school)); // cities

async与await

async

  • 如果函数返回的结果不是Promise对象,则函数返回一个Promise对象
  • 如果函数返回的是一个Promise对象,可以调用then,返回值返回Promise传入的参数 resolve(“params”);
  async function fn() {return 'aaa';}console.log(fn());/*__proto__: Promise
[[PromiseState]]: "fulfilled"
[[PromiseResult]]: "aaa"*/
async function fn() {return new Promise((resolve, reject) => {resolve("success");reject("failed");});
}let result = fn();
console.log(result);
/*
* __proto__: Promise
[[PromiseState]]: "fulfilled"
[[PromiseResult]]: "success"*/  // 这里与上面有区别,这里是返回的Promise里面的数据result.then(value => {console.log(value);  // => success
})

await

  • 必须写在async里面
  • 返回Promise成功的值
  • Promise 失败了由try catch处理
  const p = new Promise((resolve, reject) => {resolve("成功值");})async function main() {let result = await p;console.log(result); // 成功值}main();
  const p = new Promise((resolve, reject) => {// resolve("成功值");reject("失败了");})async function main() {try {let result = await p;console.log(result); } catch (e) {console.log(e);  // 失败了}}main();

async和await合作读取文件

const fs = require("fs");function readWeiXue() {return new Promise((resolve, reject) => {fs.readFile("./resources/为学.md", (err, data) => {if(err) reject(err);resolve(data);})})
}
function readChaYang() {return new Promise((resolve, reject) => {fs.readFile("./resources/插秧诗.md", (err, data) => {if(err) reject(err);resolve(data);})})
}
function readGuanShu() {return new Promise((resolve, reject) => {fs.readFile("./resources/观书有感.md", (err, data) => {if(err) reject(err);resolve(data);})})
}async function main() {let weixue = await readWeiXue();let chayang = await readChaYang();let guanshu = await readGuanShu();console.log(weixue.toString());console.log(chayang.toString());console.log(guanshu.toString());
}
main();

ES6 B站学习笔记

文章目录

    • 1. ES6
      • let
          • 经典题目,for循环
      • const
      • 解构赋值
        • 数组解构
        • 对象解构
      • 箭头函数
      • 剩余参数
        • 数组解构与剩余参数使用
      • ES6内置扩展方法
        • 扩展运算符
        • Array的扩展方法
          • Array.from() 将伪数组转化为数组
          • find()
          • findIndex()
          • includes()
        • String的扩展方法
          • 模板字符串
          • startsWith() endsWith()
          • repeat()
      • Set 数据结构
      • Map数据结构
      • ES6对象简化写法
      • ES6允许给参数赋值初始值
      • Symbol
        • Symbol内置值
      • 迭代器
        • 自定义迭代器
      • 生成器
        • 生成器函数实例
      • Promise
        • then方法
        • 链式调用(then里面的函数可以回promise对象)
        • catch方法
      • 对象扩展方法
        • Object.is
        • Object.assign
        • Object.setPrototypeOf 设置原型对象
        • Object.getPrototypeOf获取原型对象
      • async与await
        • async
        • await
        • async和await合作读取文件

1. ES6

let

  • let声明的变量只在所处于的块级别有效
  • 不存在变量提升(就是不能先使用再声明)
  • 暂时性死区:一旦块级作用域定义了这个变量,外面定义的变量和这个变量就没关系了
var num = 10;
if(true){console.log(num); // num not definedlet num = 20;
}var num = 10;if(true){let num = 20;console.log(num); // => 20}
  • 不影响作用域链
{let school = 'school';function fn() {console.log(school);  // => 'school'}fn();
}
经典题目,for循环
// 变量i是全局的,函数执行时输出的都是全局作用域下的i值。var arr = [];for (var i = 0; i < 2; i++) {arr[i] = function () {console.log(i); }}arr[0](); // 2arr[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

const

  • 声明常量,常量就是值(内存地址)不能变化的量

  • const也具有块级作用域

  • 声明必须赋初始值

  • 复杂数据类型(对象数组)内部值可以更改,比如数组arr[0] = 1是允许的

解构赋值

数组解构

let ary = [1, 2 ,3];
let [a, b, c, d, e] = ary;
console.log(a); // 1
console.log(b); // 2
console.log(c); // 3
console.log(d); // undefined
console.log(e); // undefined

对象解构

  • 对象解构允许我们使用变量的名字匹配对象的属性,匹配成功就将对象的属性的值赋值给变量
let person = {name: 'andy', age: 18, sex: '男'};
let {name, age, sex} = person;
console.log(name); // 'andy'
console.log(age); // 18
console.log(sex); // '男'
let person = {name: 'andy', age: 18, sex: '男'};
let {name: myName} = person;
//  用name匹配person的name再把值赋值给myName,name只用于匹配,myName才是真正变量
console.log(myName); // 'andy'

箭头函数

  • 箭头函数是用来简化函数定义的
  • 如果函数体只有一句代码,并且代码的执行结构就是函数的返回值,那么大括号可以省略
const sum = (a, b) => n1 + n2;
const result = sum(10, 20);
console.log(result); // => 30 
  • 形参只有一个就可以省略
const fn = v => {alert(v);
}; 
fn(20);
  • 箭头函数不绑定this 没有自己的this关键字,如果在箭头函数里面使用this,指向箭头函数定义位置(声明时所在作用域下 this 的值)中的this
function fn() {console.log(this);return () => {console.log(this);}
}const obj = {name: 'zhangsan'};
const resFn = fn.call(obj);
resFn(); // => obj obj
var obj = {age: 20,say: () => {alert(this.age);}
}obj.say(); // undefined
//对象中不存在作用域,所以say实际上是被定义在window,但是window没有age属性

剩余参数

  • ES5获取剩余参数的方式
function data() {console.log(arguments);  
}
data('a', 'b', 'c');  // => Arguments(3) ["a", "b", "c", callee: ƒ, Symbol(Symbol.iterator): ƒ]
  • 剩余参数语法允许我们将不定数量的参数作为实参
const sum = (...args) => {let total = 0;args.forEach(item => total += item);return total;
};
console.log(sum(10, 20)); // 30
cossole.log(sum(10, 20, 30)); // 60

数组解构与剩余参数使用

let ary1 = ['a', 'b', 'c'];
let [s1, ...s2] = ary1;
console.log(s1); // 'a'
console.log(s2); // ['b', 'c']

ES6内置扩展方法

扩展运算符

  • 扩展运算符可以将数组或者对象转为用 , 分隔的参数序列
let ary = [1, 2, 3];
console.log(...ary); // 1 2 3
console.log(1, 2, 3); // 1 2 3
// 两种等价,扩展运算符可以将数组或者对象转为用 , 分隔的参数序列,...ary等同于 1,2,3,再打印就没有逗号了
  • 合并数组
// method 1
let ary1 = [1, 2, 3];
let ary2 = [4, 5, 6];
let ary3 = [...ary1, ...ary2];// method 2
ary1.push(.ary2);
  • 利用扩展运算符将伪数组转换为真数组
var divs = document.getElementsByTagName('div');
var ary = [...divs];
// 就可以调用数组的api了

Array的扩展方法

Array.from() 将伪数组转化为数组
  • 方法还可以接受第二个参数,作用类似于数组的map方法,用来对每个元素进行处理,将处理后的值放入返回的数组。
var arrayLike = {"0": "1","1": "2","length": 2
}var ary = Array.from(arrayLike, item => item * 2)
console.log(ary) // => (2) [2, 4]
find()
  • 用于找出第一个符合条件的数组成员,如果没有找到返回undefined
var ary = [{id: 1,name: '张三'
}, {id: 2,name: '李四'
}];
let target = ary.find(item => item.id == 3);
console.log(target) // => undefined
findIndex()
  • 用于找出第一个符合条件的数组成员的位置,如果没有找到返回-1
let ary = [10, 20, 50];
let index = ary.findIndex(item => item > 15);
console.log(index) // => 1
includes()
  • 表示某个数组是否包含给定的值,返回布尔值。
let ary = ["a", "b", "c"];let result = ary.includes('a')
console.log(result) // => true
result = ary.includes('e')
console.log(result) // => false

String的扩展方法

模板字符串
  • ES6新增的创建字符串的方式,使用反引号定义
let name = `这是一个模板字符串`;
console.log(name); // => '这是一个模板字符串'
  • 模板字符串可以解析变量
let name = `张三`;
let sayHello = `hello, my name is ${name}`;
console.log(sayHello); // => hello, my name is 张三
  • 模板字符串可以换行
let result = {name: 'zhangsan',age: 20
};let html = `
<div><span>${result.name}</span>
</div>
`
console.log(html);
/*
<div><span>zhangsan</span>
</div>
*/
  • 在模板字符串中可以调用函数
const fn = () => {return '我是fn函数'
}
let html = `我是模板字符串${fn()}`;
console.log(html) // => 我是模板字符串我是fn函数
startsWith() endsWith()
  • startsWith():表示参数字符串是否在原字符串的头部,返回布尔值
  • endsWith(): 表示参数字符是否在原字符串的尾部,返回布尔值
let str = 'hello es6';
let r1 = str.startsWith('hello');
console.log(r1); // true
let r2 = str.endsWith('es6');
console.log(r2); // false
repeat()
  • 将原字符串重复n次,返回新字符串
console.log('xy'.repeat(2)); // xyxy

Set 数据结构

  • 类似数组,但是成员唯一
  • Set本身是一个构造函数,用来生产Set数据结构
const s = new Set();
console.log(s.size); // 0
  • Set函数可以接受一个数组作为参数来初始化
const set = new Set([1, 2, 3, 4]);
console.log(set.size); //4
  • 用set来去重
const s3 = new Set([1, 2, 3, 3]);
console.log(s3.size); // => 3
const ary = [...s3];
console.log(ary); // => [1, 2, 3]
  • add(value):添加某个值,返回set本身
  • delete(value):删除某个值,返回一个布尔值,表示删除是否成功
  • has(value):返回一个布尔值,表示该值是否为set成员
  • clear():清楚所有成员,没有返回值
  • foreach遍历

Map数据结构

  • ES6 提供了 Map 数据结构。它类似于对象,也是键值对的集合。但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。Map 也实现了iterator 接口,所以可以使用『扩展运算符』和『for…of…』进行遍历。Map 的属性和方法:
    • size 返回 Map 的元素个数
    • set 增加一个新元素,返回当前 Map
    • get 返回键名对象的键值
    • has 检测 Map 中是否包含某个元素,返回 boolean 值
    • clear 清空集合,返回 undefined
  //声明 Maplet m = new Map();//添加元素m.set('name', 'xiaoming');m.set('change', function () {console.log("change");});let key = {school: 'ATGUIGU'};m.set(key, ['北京', '上海', '深圳']);//sizeconsole.log(m.size);//删除m.delete('name');//获取console.log(m.get('change'));//清空m.clear();//遍历for (let v of m) {console.log(v);}

ES6对象简化写法

let name = 'aaa';
let improve = function () {console.log('improve');
}//属性和方法简写
let atguigu = {name,improve,change() { // change: function(){}console.log('change')}
};

ES6允许给参数赋值初始值

function add (a, b, c = 10) {return a + b + c;
}
let result = add(1, 2);
console.log(result); // => 13
  • 与解构赋值结合
function connect({host = '127.0.0.1', username, password, port}) { // 127.0.0.1默认值 //log host username password port
}connect({host: 'localhost',username: 'root',password: 'root',port: 3306
})

Symbol

ES6 引入了一种新的原始数据类型 Symbol,表示独一无二的值。它是JavaScript 语言的第七种数据类型,是一种类似于字符串的数据类型。

  • 用Synmbol创建的值不能与其他数据进行运算
  • 创建Symbol
let s = Symbol();
console.log(s, typeof f);
let s2 = Symbol('a');
let s2_2 = Symbol('a');
console.log(s2 === s2_2); // false//使用 Symbol for 定义
let s3 = Symbol.for('a');
let s3_2 = Symbol.for('a');
console.log(s3 === s3_2); // true

Symbol内置值

Symbol.hasInstance当其他对象使用 instanceof 运算符,判断是否为该对象的实例时,会调用这个方法
Symbol.isConcatSpreadable对象的 Symbol.isConcatSpreadable 属性等于的是一个布尔值,表示该对象用于 Array.prototype.concat()时,是否可以展开。
Symbol.species创建衍生对象时,会使用该属性
Symbol.match当执行 str.match(myObject) 时,如果该属性存在,会调用它,返回该方法的返回值。
Symbol.replace当该对象被 str.replace(myObject)方法调用时,会返回该方法的返回值。
Symbol.search当该对象被 str. search (myObject)方法调用时,会返回该方法的返回值。
Symbol.split当该对象被 str. split (myObject)方法调用时,会返回该方法的返回值。
Symbol.iterator对象进行 for…of 循环时,会调用 Symbol.iterator 方法,返回该对象的默认遍历器
Symbol.toPrimitive该对象被转为原始类型的值时,会调用这个方法,返回该对象对应的原始类型值。
Symbol. toStringTag在该对象上面调用 toString 方法时,返回该方法的返回值
Symbol. unscopables该对象指定了使用 with 关键字时,哪些属性会被 with环境排除。
class Person {static[Symbol.hasInstance](param) {console.log(param);console.log("被检测了");return false;}
}let o = {};
console.log(o instanceof Person); 
// => {} 被检测了 false 

迭代器

遍历器(Iterator)就是一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作。

  1. ES6 创造了一种新的遍历命令 for…of 循环,Iterator 接口主要供 for…of 消费

  2. 原生具备 iterator 接口的数据(可用 for of 遍历)

a) Array

b) Arguments

c) Set

d) Map

e) String

f) TypedArray

g) NodeList

const xiyou = ['tangseng', 'sunwukong', 'zhubajie', 'shaseng'];
for(let v of xiyou) {console.log(v); // 'tangseng' 'sunwukong' 'zhubajie' 'shaseng'
} 

自定义迭代器

  • 用for of 自定义遍历对象中的某个数组
let banji = {name: '一班',stus: ['xiaoming','xiaoning','xiaotian','knight'],[Symbol.iterator]() {let index = 0;let that = this;return {next: function() {if(index < that.stus.length) {index++;return {vlaue: that.stus[i], done: false};} else {return {value: undefined, done: true};}}};}
}for(let v of banji) {console.log(v); // 'xiaoming' 'xiaoning' 'xiaotian' 'knight'
}

生成器

生成器函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同

  • 生成器函数返回的结果是迭代器对象,调用迭代器对象的 next 方法可以得到yield语句后的值
  • yield 相当于函数的暂停标记,也可以认为是函数的分隔符,每调用一次 next方法,执行一段代码
function * gen(){yield '一只没有耳朵';yield '一只没有尾巴';return '真奇怪';
}let iterator = gen();
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
/*
{value: "一只没有耳朵", done: false}
{value: "一只没有尾巴", done: false}
{value: "真奇怪", done: true}
{value: undefined, done: true}
*/
  • next 方法可以传递实参,作为 yield 语句的返回值
function * gen(){let one = yield 111;console.log(one);yield 222;
}
let iterator = gen();
console.log(iterator.next()); // {value: 111, done: false} 
console.log(iterator.next('BBB')); // 'BBB' {value: 222, done: false} 

生成器函数实例

  • 场景:先获取用户名,一秒后再获取用户订单,一秒后再获取用户订单里的商品
function getUsers() {setTimeout(() => {let data = 'userData';iterator.next(data);}, 1000)
}
function getOrders() {setTimeout(() => {let data = 'orderData';iterator.next(data);}, 1000)
}
function getGoods() {setTimeout(() => {let data = 'goodsData';iterator.next(data);}, 1000)
}function * gen() {let users = yield getUsers();console.log(users);let orders = yield getOrders();console.log(orders);let goods = yield getGoods();console.log(goods);
}let iterator = gen();
iterator.next(); // userData (1s) orderData (1s) goodsData

Promise

  • Promise 是 ES6 引入的异步编程的新解决方案。语法上 Promise 是一个构造函数,用来封装异步操作并可以获取其成功或失败的结果。

  • Promise 构造函数: Promise (excutor) {}

  • Promise.prototype.then 方法

  • Promise.prototype.catch 方法

  • 实例化Promise

const p = new Promise(function(resolve, reject) {setTimeout(function() {//let data = 'data';//resolve(data);let err = 'err';reject(err);}, 1000)
});p.then(function(value) {console.log(value);
}, function(reason) {console.log(reason);
}) // => reason
// 当setTimeout里面的函数调用resolve的时候,p的状态变为success,p.then调用第一个回调函数
// 当setTimeout里面的函数调用reject的时候,p的状态变为fail,p.then调用第二个回调函数
  • 用Promise封装文件读取
const fs = require('fs');fs.readFile('./resources/为学.md', (err, data) => {if (err) throw err;console.log(data.toString());
});// --------------------------封装-------------------------------------------
const p = new Promise((resolve, reject) => {fs.readFile('./resources/为学.mda', (err, data) => {if(err) reject(err);resolve(data);})
});p.then(value => {console.log(value.toString());
}, reason => {console.log(reason);
})
  • 用Promise封装AJAX
  // 创建const xhr = new XMLHttpRequest();// 初始化xhr.open("GET", "/getJoke");// 发送xhr.send();// 绑定事件xhr.onreadystatechange = function () {if (xhr.readyState === 4) {if (xhr.status >= 200 && xhr.status < 300) {console.log(xhr.response); // => ...} else {console.log(xhr.status);}}}// --------------------------------封装--------------------------------------const p = new Promise((resolve, reject) => {// 创建const xhr = new XMLHttpRequest();// 初始化xhr.open("GET", "/getoke");// 发送xhr.send();// 绑定事件xhr.onreadystatechange = function () {if (xhr.readyState === 4) {if (xhr.status >= 200 && xhr.status < 300) {resolve(xhr.response);} else {reject(xhr.status);}}}});p.then(value => {console.log(value);}, reason => {console.error(reason);   //404})

then方法

  • 调用then方法返回的结果是Promise对象
const p = new Promise((resolve, reject) => {setTimeout(() => {resolve('data');}, 1000)
});const result = p.then(value => {console.log(value);return 'aaa';
}, reason => {console.warn(reason);
});console.log(result);
/*
Promise {<pending>}
__proto__: Promise
[[PromiseState]]: "fulfilled"
[[PromiseResult]]: "aaa"'data'
*/

链式调用(then里面的函数可以回promise对象)

const p = new Promise((resolve, reject) => {setTimeout(() => {resolve('data');}, 1000)
});p.then(value => {return new Promise((resolve, reject) => {resolve('ok');// reject('no');})
}).then(value => {})
  • 链式调用demo
const fs = require("fs");const p = new Promise((resolve, reject) => {fs.readFile('./resources/为学.md', (err, data) => {if(err) reject(err);resolve(data);})
});p.then(value => {console.log(value.toString());return new Promise((resolve, reject) => {fs.readFile('./resources/插秧诗.md', (err, data) => {if(err) reject(err);resolve(data);})})
}, reason => {console.error(reason);
}).then(value => {console.log(value.toString());return new Promise((resolve, reject) => {fs.readFile('./resources/观书有感.md', (err, data) => {if(err) reject(err);resolve(data);})})
}, reason => {console.error(reason);
}).then(value => {console.log(value.toString());
}, reason => {console.error(reason);
})

catch方法

  • Promise.prototype.catch方法是.then(null,rejection)的别名,用于指定发生错误时的回调函数,算是语法糖
p.then((val) => console.log('fulfilled:', val)).catch((err) => console.log('rejected', err));// 等同于
p.then((val) => console.log('fulfilled:', val)).then(null, (err) => console.log("rejected:", err));

对象扩展方法

Object.is

  • 判断两个值是否完全相等
console.log(Object.is(120, 120)); // true
console.log(Object.is(NaN, NaN)); // true
console.log(NaN, NaN) // false

Object.assign

  • 对象的合并

  • 都有后面把前面覆盖,前有后没有保留,后没有前有省去

const o1 = {host: 'loacalhost',port: 3306,test: 'test'
}
const o2 = {host: '',port: 33060,test2: 'test2'
}console.log(Object.assign(o1, o2));
/*
{    host: '',port: 33060,test: 'test'
}
*/

Object.setPrototypeOf 设置原型对象

Object.getPrototypeOf获取原型对象

const school = {name: 'xiaoming'
}
const cities = {city: ['beijing', 'shanghai']
}
Object.setPrototypeOf(school, cities);
console.log(school); // school原型是cities
console.log(Object.getPrototypeOf(school)); // cities

async与await

async

  • 如果函数返回的结果不是Promise对象,则函数返回一个Promise对象
  • 如果函数返回的是一个Promise对象,可以调用then,返回值返回Promise传入的参数 resolve(“params”);
  async function fn() {return 'aaa';}console.log(fn());/*__proto__: Promise
[[PromiseState]]: "fulfilled"
[[PromiseResult]]: "aaa"*/
async function fn() {return new Promise((resolve, reject) => {resolve("success");reject("failed");});
}let result = fn();
console.log(result);
/*
* __proto__: Promise
[[PromiseState]]: "fulfilled"
[[PromiseResult]]: "success"*/  // 这里与上面有区别,这里是返回的Promise里面的数据result.then(value => {console.log(value);  // => success
})

await

  • 必须写在async里面
  • 返回Promise成功的值
  • Promise 失败了由try catch处理
  const p = new Promise((resolve, reject) => {resolve("成功值");})async function main() {let result = await p;console.log(result); // 成功值}main();
  const p = new Promise((resolve, reject) => {// resolve("成功值");reject("失败了");})async function main() {try {let result = await p;console.log(result); } catch (e) {console.log(e);  // 失败了}}main();

async和await合作读取文件

const fs = require("fs");function readWeiXue() {return new Promise((resolve, reject) => {fs.readFile("./resources/为学.md", (err, data) => {if(err) reject(err);resolve(data);})})
}
function readChaYang() {return new Promise((resolve, reject) => {fs.readFile("./resources/插秧诗.md", (err, data) => {if(err) reject(err);resolve(data);})})
}
function readGuanShu() {return new Promise((resolve, reject) => {fs.readFile("./resources/观书有感.md", (err, data) => {if(err) reject(err);resolve(data);})})
}async function main() {let weixue = await readWeiXue();let chayang = await readChaYang();let guanshu = await readGuanShu();console.log(weixue.toString());console.log(chayang.toString());console.log(guanshu.toString());
}
main();

与本文相关的文章

发布评论

评论列表 (0)

  1. 暂无评论