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 接口,就可以完成遍历操作。
-
ES6 创造了一种新的遍历命令 for…of 循环,Iterator 接口主要供 for…of 消费
-
原生具备 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 接口,就可以完成遍历操作。
-
ES6 创造了一种新的遍历命令 for…of 循环,Iterator 接口主要供 for…of 消费
-
原生具备 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();