let
特性
- 变量不能重复声明
- 块级作用域
- 不存在变量提升
- 不影响作用域链。?
const
- 声明时必须赋初始值。
- 一般大写。
- 不能修改
- 块级作用域
- 对于数组和对象的修改不算做对常量的修改。因为指向的地址并没有改变。
变量的解构赋值
- 数组
- 对象
模板字符串
-
声明:``反引号
-
内容中可以出现换行符
-
变量拼接
let a = '魏翔'; let b = `$(a)是个演员`; // b === 魏翔是个演员
-
对象的简化写法
-
允许在大括号里面直接写入变量和函数,作为对象的属性和方法。
// 原来 const school = { name: name, // 变量名相同就可以不用写两次 change: change, improve: function(){} } // 现在 const school = { name, change, improve(){} // 函数的书写简化 }
箭头函数以及声明特点
-
// 原来 let fn = function () {} // 现在 let fn = () => {}
-
特性:
- this是静态的,始终指向函数声明时所在作用域下的This值
- 不能作为构造函数实例化对象
- 不能使用arguments变量
- 简写
- 省略小括号,当有且只有一个形参
- 省略花括号{},当代码体只有一条语句,此时return也要省略掉
-
应用场景
-
// 返回偶数 const arr = [0,1,2,3,4]; const result = arr.filter(function (item) { // return item % 2 === 0 ? true : false }) // 箭头函数写法 const result = arr.filter(item => item % 2 === 0)
-
箭头函数适合与this无关的回调,定时器,数组的方法回调;
-
箭头函数不适合于this有关的回调。事件回调,对象的方法
-
函数参数默认值设置
- 形参初始值 具有默认值的参数,有默认值的一般在最后。(感觉就是解构赋值相关)
- 与解构赋值相结合,函数传参时可以直接{name,age}写到传参的小括号里,函数里面就可以直接用
rest参数
-
用于获取函数的实参,用来代替arguments
// 原来 function date(){ console.log(arguments); } date('1','2','3'); //这个会输出obj{} // 现在 function date(...args) { console.log(args); } date('1','2','3'); // 这个会输出数组[] ...args指的就是rest参数,必须放在最后
扩展运算符
-
… 将数组转换为逗号分隔的参数序列
const tf = ['1','2','3']; function fn(){ console.log(arguments); } fn(...tf); // 输出三个值 fn(tf); // 输出一个值
-
应用
-
数组合并
const nums1 = [1,2]; const nums2 = [3,4]; const nums3 = nums1.concat(nums2); // [1, 2, 3, 4] const nums4 = [...nums1, ...nums2]; // [1, 2, 3, 4] console.log(nums3); console.log(nums4);
-
数组克隆
const nums1 = [1,2]; const nums2 = [...nums1]; // 浅拷贝 [1,2] console.log(nums2);
-
将伪数组转为真正的数组
...伪数组名称
-
symbol
-
特点
- 第七种数据类型,类似于字符串,值唯一
- 不能与其他数据进行运算
- 使用symbol定义的对象属性不能使用for in 循环遍历,但是可以使用Reflect.ownKeys来获取对象的所有键名
// 创建symbol const s1 = Symbol(); const s2 = Symbol('zhangsan'); const s3 = Symbol('zhangsan'); console.log(s2 === s3); // false const s4 = Symbol.for('zhangsan'); const s5 = Symbol.for('zhangsan'); console.log(s4 === s5); // true
-
不能与数据进行运算,也不能自己+自己
-
7种数据类型:number string boolean object null undefined symbol
-
应用场景:给对象添加属性和方法 (可能重点是比较安全?能成功添加进去?)
-
// 方法一 let game = { name: '俄罗斯方块', up: Symbol(), down: Symbol() }; let methods = { up: Symbol(), down: Symbol() }; game[methods.up] = function(){ console.log('11111'); } game[methods.down] = function(){ console.log('22222'); } console.log(game); // {name: '俄罗斯方块', up: Symbol(), down: Symbol(), Symbol(): ƒ, Symbol(): ƒ} // 虽然本来就有,但是安全地添加进去了 // 方法二 let game1 = { name: '狼人杀', [Symbol('say')]: function(){console.log('发言')}, [Symbol('paly')]: function(){console.log('玩耍')} } console.log(game1); // {name: '狼人杀', Symbol(say): ƒ, Symbol(paly): ƒ}
-
-
symbol内置值 11个 将symbol.xxx这个整体作为对象的属性,是为了扩展对象的属性。
迭代器Iterator
-
接口,任何数据结构只要部署了iterator接口,就可以用for of来遍历。
-
iterator接口就是对象的一种属性,这个属性的名字是symbol.iterator
-
for in和for of的区别:for in保存的是键,比如数组序号0123;for of保存的是值,比如nums[1]nums[2]
-
具备iterator接口的:Array Arguments Set Map String TypedArray NodeList
-
原理:
- 创建一个指针对象,指向当前数据结构的起始位置
- 第一次调用next方法,指针自动指向第一个成员
- 不断调用next,指针不断后移,直至指向最后一个
- 每调用一次next方法返回一个包含value和done属性的对象,done代表遍历是否已经完成
-
应用
-
需要自定义遍历数据的时候,需要用到迭代器
// 相当于自己去创建索引,自己写接口? const banji = { name: '终极一班', stus: [ 'xiaoming', 'xiaolan', 'xiaochun', 'king' ], [Symbol.iterator]() { let index = 0; let _this = this; return { next: function () { if (index < _this.stus.length) { const result = {value: _this.stus[index], done: false}; index++; return result; } else { return {value: undefined, done: true} } } } } } for (let x of banji) { console.log(x); }
-
生成器
-
一种特殊的函数,常用于异步编程。function* ()
-
里面有迭代器,可以用next调用。yield相当于分隔符。
-
第二次调用next时传参,这个参数将会作为第一个yield语句的返回值。
-
异步编程。主要是IO相关的,文件操作,网络操作(Ajax,request),数据库操作
-
需求:1s后控制台输出111 再过2s后222 再过3s后333
setTimeout(() => { console.log(111); setTimeout(() => { console.log(222); setTimeout(() => { console.log(333); }, 3000) }, 2000) }, 1000); // 可以实现,但是冗余。回调地狱。
function one() { setTimeout(() => { console.log(111); }, 1000) } function two() { setTimeout(() => { console.log(222); }, 2000) } function three() { setTimeout(() => { console.log(333); }, 3000) } one(); two(); three(); // 这样写是顺序执行,启动了三个独立的定时器,是在1,2,3秒打印,不能实现功能 function one() { setTimeout(() => { console.log(111); iterator.next(); }, 1000) } function two() { setTimeout(() => { console.log(222); iterator.next(); }, 2000) } function three() { setTimeout(() => { console.log(333); iterator.next(); }, 3000) } function * gen() { yield one(); yield two(); yield three(); } let iterator = gen(); iterator.next(); // 这段代码使用了生成器函数,可以实现功能,且缩进是有限的,不会产生回调地狱。
-
需求: 模拟获取:先获取用户数据,然后订单数据,然后商品数据
function getUsers() { setTimeout(() => { let data = '用户数据'; iterator.next(data); }, 1000) } function getOrders() { setTimeout(() => { let data = '订单数据'; iterator.next(data); }, 1000) } function getGoods() { setTimeout(() => { let data = '商品数据'; 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();
Promise
-
异步编程。是一个构造函数,可以用来封装异步操作并获取她成功或者失败的结果。
-
示例
const p = new Promise(function (resolve, reject) { setTimeout(function(){ let data = '数据库中的数据'; resolve(data); let err = '获取失败'; reject(err); }, 1000); }); p.then(function(value){ console.log(value); // 如果获取成功,那么调用这里 }, function(reason){ console.log(reason); // 如果失败,调用这里 })
-
promise读取文件
// 1. 引入fs模块 const fs = require('fs'); // 2. 调用方法读取文件 // fs.readFile('./files/待读取文件1.md', (err, data) => { // if(err) { // throw err; // } // console.log(data.toString()); // }) // 3.使用promise封装 const p = new Promise(function (resolve, reject) { fs.readFile('./files/待读取文件1.md', (err, data) => { if (err) reject(err); // 如果失败 resolve(data); }); }); p.then(function (value){ console.log(value.toString()); }, function (reason){ console.log('读取失败!!!'); }); 改为箭头函数 p.then(value => { console.log(value.toString()); }, reason => { console.log('读取失败!!!'); });
-
promise封装Ajax请求
-
promise的then方法
-
then指定回调,成功执行value,失败执行reason
-
then的返回结果是promise对象,这个对象的状态由回调函数决定。如果返回结果是非promise结果(比如return ‘123’),那么状态状态为成功,且返回值为对象的成功值;如果是promise对象,那么里面的状态决定外面的状态;如果抛出错误,,,
-
可以链式调用,可以杜绝回调地狱
-
目前我对于回调地狱的理解就是不断缩进。
-
链式调用
// 读取多个文件 const fs = require('fs'); // fs.readFile('./files/待读取文件1.md', (err, data1) => { // fs.readFile('./files/待读取文件2.md', (err, data2) => { // result = data1 + '\n' + data2; // console.log(result); // }) // }) // promise const p = new Promise((resolve, reject) => { fs.readFile('./files/待读取文件1.md', (err, data) => { resolve(data); }) }) p.then(value => { return new Promise((resolve, reject) => { fs.readFile('./files/待读取文件2.md', (err, data) => { resolve([value, data]); }) }) }).then(value => { return new Promise((resolve, reject) => { fs.readFile('./files/待读取文件3.md', (err, data) => { value.push(data); resolve(value); }) }) }).then(value => { console.log(value.join('')); })
-
-
promise的catch方法
-
p.then(value => {}, reason => { console.log(reason); }); p.catch(reason => { console.warn(reason); });
-
set
-
let s = new Set(); let s2 = new Set([1,2,1,3]); s2 = (1,2,3)可以去重,括号里的参数是可迭代对象
-
s.size add delete has clear()
-
有迭代器接口,可以for of遍历
-
示例
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3]; // 数组去重 // let setArr = [...new Set(arr)]; // console.log(setArr); // 交集 let arr1 = [1, 4, 5, 5, 6, 11]; // let result = [...new Set(arr)].filter(item => { // let setArr1 = new Set(arr1); // if (setArr1.has(item)) { // return true; // } else { // return false; // } // }) // let result = [...new Set(arr)].filter(item => new Set(arr1).has(item)); // 简化代码 // 并集 //let result = [...new Set([...arr, ...arr1])]; // 差集 // arr - arr1 let result = [...new Set(arr)].filter(item => !new Set(arr1).has(item)); console.log(result);
Map
-
与对象Object的区别:对象的键是字符串,Map的对象可以是任何类型。
-
有iterator接口,可以用…,可以用for of遍历
-
let m = new Map(); // 添加 m.set('name', '张三'); // 删除 m.delete('name'); // 获取 m.get('name'); // 清空 m.clear(); // 遍历 for of
Class
-
类继承ES6
class Phone { constructor(brand, price){ this.brand = brand; this.price = price; } call(){ console.log('我可以打电话'); } } class smartPhone extends Phone { constructor(brand, price, color, size) { super(brand, price); this.color = color; this.size = size; } photo(){ console.log('我可以拍照片'); } playGame(){ console.log('我可以玩游戏'); } } xiaomi = new smartPhone('xioami', '2999', 'black', '4.4'); console.log(xiaomi); // 子类可以对父类重写,相同的方法子类写了,那么调用子类时,会覆盖掉子类
-
get和set
数值扩展
- Number.EPSILON 最小精度
- 二进制0b八进制0o十六进制0x
- Number.isFinite是否有限
- Number.isNaN
- Number.parseInt Number.parseFloat
- Number.isInteger
- Math.trunc抹掉小数
- Math.sign判断正负
对象方法扩展
模块化
- export
- import
- babel