ES6学习笔记(包括ES6-ES11常用特性)
ES6
- 1.let变量声明及声明特性
- 1.1 变量声明
- 1.2 不能重复声明
- 1.3 块级作用域
- 1.4 不存在变量提升*
- 1.5 不影响作用域链
- 2. const声明常量及其特性
- 2.1 声明方法
- 3. 变量的解构赋值
- 3.1 数组的解构
- 3.2 对象的解构
- 4. 模板字符串
- 数据类型:String
- 声明:
- 内容中可以出现换行符
- 变量拼接
- 5. 对象的简化写法
- 6. 箭头函数及其声明特点
- 6.1 声明方法
- 6.2 特性
- 6.2.1 静态this
- 6.2.2 不能作为构造函数实例化对象
- 6.2.3 不能使用arguments对象
- 6.2.4 箭头函数的简写
- 6.2.4.1 省略小括号
- 6.2.4.2 省略花括号
- 6.2.4.3 案例
- 6.2.5 箭头函数的应用场景
- 7. 函数参数的默认值
- 8. rest参数
- 9. 扩展运算符
- 9.1 扩展运算符的应用
- 9.1.1 数组的合并
- 9.1.2 数组的拷贝
- 9.1.3 将维数组转换为真正的数组
- 10. Symbol数据类型
- 10.1 Symbol的创建
- 10.2 向对象中添加Symbol类型的属性
- 10.3 Symbol的内置属性
- 10.3.1 Symbol.hasInstance 对象类型检测
- 10.3.2 Symbol.isConcatSpreadable
- 11. 迭代器
- 12. 生成器函数
- 12.1 生成器函数的声明与调用
- 12.2 next方法
- 12.3 yield理解
- 13. Promise
- 13.1 Promise的基本使用
- 13.2 Promise读取文件
- 13.3 Promise封装AJAX请求
- 13.4 then方法
- 13.4.1 返回的Promise对象的状态
- 13.4.2 链式调用
- 13.5 catch方法
- 14. Set
- 15. Map
- 16. class类
- 16.1 class声明类
- 16.2 constractor定义构造函数初始化
- 16.3 extends继承父类,super调用父级构造方法
- 16.4 父类方法可以重写
- 16.5 getter和setter
- 17. 数值扩展
- 17.1 Number.EPSILON是JS最小精度
- 17.2 进制运算
- 17.3 其他
- 18. ES5-ES6对象方法拓展
- 18.1 Object.is判断两个值是否完全相等,如果是对象的话,必须是同一个引用。
- 18.2 Object.assign 对象的合并
- 18.3 Object.setPrototypeOf设置原型对象
- 19. 模块化
- 19.1 模块暴露语法汇总
- 19.1.1 分别暴露
- 19.1.2 统一暴露
- 19.1.3 默认暴露(VUE常用)
- 19.2 模块引入语法汇总
- 19.2.1 通用的导入方式
- 19.2.2 解构赋值的形式
- 19.3.3 简便形式(only默认暴露)
- 19.3 入口文件方式
- 20. ES7新特性
- 20.1 **幂运算
- 21. ES8新特性
- 21.1 async
- 21.2 await
- 21.3 async await 读取文件
- 21.4 async,await封装ajax请求
- 22. ES8对象方法拓展
- 22.1 Object.values()和Object.entries()
- 22.2 Object.getOwnPropertyDescriptors获取对象属性的描述对象
- 23. ES9
- 23.1 rest参数
- 23.2 扩展运算符
- 24. ES10新特性
- 24.1 Object.fromEntries()
- 24.2 字符串方法 trimStart()和trimEnd()
- 24.3 数组方法 flat()和flatMap()
- 24.4. 私有属性
- 24.5 Promise.Allsettled()方法
- 24.6 ==可选链操作符==
- 24.7 动态引入
- 24.8 BigInt类型
1.let变量声明及声明特性
1.1 变量声明
let a;let b, c, d;let e = 100;let f = 1, g = 2, h = 3;
1.2 不能重复声明
let star='a'let star='b'
报错,但是var可以
1.3 块级作用域
全局,函数,eval
{let girl = '丁心宜'
}
console.log(girl)
let 打印不出,var 可以
1.4 不存在变量提升*
console.log(song)
let song = '小燕子穿花衣'
会报错
但是用var相当于
var song;
console.log(song)
let song='小燕子穿花衣'
//undefined
不报错
1.5 不影响作用域链
虽然是块级作用域,但不影响作用域链
作用域链(Scoped chain)
:由子级作用域返回父级作用域中寻找变量,就叫做作用域链。
{let score = '120'function fn1() {let school = '山东大学'function fn() {console.log(school);console.log(score)}fn();}fn1()}
两个变量都能打印出来。这里为了说明问题,用了两层,其实多少层都能寻找到变量。
2. const声明常量及其特性
文章目录
- 1.let变量声明及声明特性
- 1.1 变量声明
- 1.2 不能重复声明
- 1.3 块级作用域
- 1.4 不存在变量提升*
- 1.5 不影响作用域链
- 2. const声明常量及其特性
- 2.1 声明方法
- 3. 变量的解构赋值
- 3.1 数组的解构
- 3.2 对象的解构
- 4. 模板字符串
- 数据类型:String
- 声明:
- 内容中可以出现换行符
- 变量拼接
- 5. 对象的简化写法
- 6. 箭头函数及其声明特点
- 6.1 声明方法
- 6.2 特性
- 6.2.1 静态this
- 6.2.2 不能作为构造函数实例化对象
- 6.2.3 不能使用arguments对象
- 6.2.4 箭头函数的简写
- 6.2.4.1 省略小括号
- 6.2.4.2 省略花括号
- 6.2.4.3 案例
- 6.2.5 箭头函数的应用场景
- 7. 函数参数的默认值
- 8. rest参数
- 9. 扩展运算符
- 9.1 扩展运算符的应用
- 9.1.1 数组的合并
- 9.1.2 数组的拷贝
- 9.1.3 将维数组转换为真正的数组
- 10. Symbol数据类型
- 10.1 Symbol的创建
- 10.2 向对象中添加Symbol类型的属性
- 10.3 Symbol的内置属性
- 10.3.1 Symbol.hasInstance 对象类型检测
- 10.3.2 Symbol.isConcatSpreadable
- 11. 迭代器
- 12. 生成器函数
- 12.1 生成器函数的声明与调用
- 12.2 next方法
- 12.3 yield理解
- 13. Promise
- 13.1 Promise的基本使用
- 13.2 Promise读取文件
- 13.3 Promise封装AJAX请求
- 13.4 then方法
- 13.4.1 返回的Promise对象的状态
- 13.4.2 链式调用
- 13.5 catch方法
- 14. Set
- 15. Map
- 16. class类
- 16.1 class声明类
- 16.2 constractor定义构造函数初始化
- 16.3 extends继承父类,super调用父级构造方法
- 16.4 父类方法可以重写
- 16.5 getter和setter
- 17. 数值扩展
- 17.1 Number.EPSILON是JS最小精度
- 17.2 进制运算
- 17.3 其他
- 18. ES5-ES6对象方法拓展
- 18.1 Object.is判断两个值是否完全相等,如果是对象的话,必须是同一个引用。
- 18.2 Object.assign 对象的合并
- 18.3 Object.setPrototypeOf设置原型对象
- 19. 模块化
- 19.1 模块暴露语法汇总
- 19.1.1 分别暴露
- 19.1.2 统一暴露
- 19.1.3 默认暴露(VUE常用)
- 19.2 模块引入语法汇总
- 19.2.1 通用的导入方式
- 19.2.2 解构赋值的形式
- 19.3.3 简便形式(only默认暴露)
- 19.3 入口文件方式
- 20. ES7新特性
- 20.1 **幂运算
- 21. ES8新特性
- 21.1 async
- 21.2 await
- 21.3 async await 读取文件
- 21.4 async,await封装ajax请求
- 22. ES8对象方法拓展
- 22.1 Object.values()和Object.entries()
- 22.2 Object.getOwnPropertyDescriptors获取对象属性的描述对象
- 23. ES9
- 23.1 rest参数
- 23.2 扩展运算符
- 24. ES10新特性
- 24.1 Object.fromEntries()
- 24.2 字符串方法 trimStart()和trimEnd()
- 24.3 数组方法 flat()和flatMap()
- 24.4. 私有属性
- 24.5 Promise.Allsettled()方法
- 24.6 ==可选链操作符==
- 24.7 动态引入
- 24.8 BigInt类型
2.1 声明方法
const 变量名 = 值
注意事项:
- 声明的时候要赋初值*
- 一般常量名全部大写(潜规则)
- 常量不能重新赋值
- 块级作用域*
{const PLATER='DXY'
}
console.log(PLAYER)
//ERROR:not defined
- 对于数组和对象的元素修改,因为地址没有发生改变,因此不算做对常量的修改,不会报错*
const ARR = [1,2,3,4]
ARR.push(5)
// 不报错
3. 变量的解构赋值
3.1 数组的解构
const F4=['迪丽热巴','古力娜扎','杨幂','刘诗诗'];
let [di,gu,yang,liu] = F4;
console.log(di)
//迪丽热巴
3.2 对象的解构
const zhao = {name: '赵本山',age: '不详',xiaopin: function(){console.log('我可以演小品')}
}
let {name,age,xiaopin} = zhao
xiaopin()
// 或者
let {xiaopin} = zhao
xiaopin()
4. 模板字符串
数据类型:String
声明:
let str=`模板字符串`
内容中可以出现换行符
变量拼接
let lovest = 'AngelaBaby';
let out = `${lovest} is the BEST actress in my heart!`
5. 对象的简化写法
ES6允许在大括号里面直接写入变量和函数,作为对象的属性和方法。方法的写法也可以省略。
let name = 'dxy'let age = 21let speak = function () {console.log('我爱说废话');}const person = {name, // 即:name:nameage, // 即:age:agespeak // 即:speak.speakimprove(){console.log(111)}/*等同于:improve:functon(){console.log(111)}**/}person.speak()
6. 箭头函数及其声明特点
文章目录
- 1.let变量声明及声明特性
- 1.1 变量声明
- 1.2 不能重复声明
- 1.3 块级作用域
- 1.4 不存在变量提升*
- 1.5 不影响作用域链
- 2. const声明常量及其特性
- 2.1 声明方法
- 3. 变量的解构赋值
- 3.1 数组的解构
- 3.2 对象的解构
- 4. 模板字符串
- 数据类型:String
- 声明:
- 内容中可以出现换行符
- 变量拼接
- 5. 对象的简化写法
- 6. 箭头函数及其声明特点
- 6.1 声明方法
- 6.2 特性
- 6.2.1 静态this
- 6.2.2 不能作为构造函数实例化对象
- 6.2.3 不能使用arguments对象
- 6.2.4 箭头函数的简写
- 6.2.4.1 省略小括号
- 6.2.4.2 省略花括号
- 6.2.4.3 案例
- 6.2.5 箭头函数的应用场景
- 7. 函数参数的默认值
- 8. rest参数
- 9. 扩展运算符
- 9.1 扩展运算符的应用
- 9.1.1 数组的合并
- 9.1.2 数组的拷贝
- 9.1.3 将维数组转换为真正的数组
- 10. Symbol数据类型
- 10.1 Symbol的创建
- 10.2 向对象中添加Symbol类型的属性
- 10.3 Symbol的内置属性
- 10.3.1 Symbol.hasInstance 对象类型检测
- 10.3.2 Symbol.isConcatSpreadable
- 11. 迭代器
- 12. 生成器函数
- 12.1 生成器函数的声明与调用
- 12.2 next方法
- 12.3 yield理解
- 13. Promise
- 13.1 Promise的基本使用
- 13.2 Promise读取文件
- 13.3 Promise封装AJAX请求
- 13.4 then方法
- 13.4.1 返回的Promise对象的状态
- 13.4.2 链式调用
- 13.5 catch方法
- 14. Set
- 15. Map
- 16. class类
- 16.1 class声明类
- 16.2 constractor定义构造函数初始化
- 16.3 extends继承父类,super调用父级构造方法
- 16.4 父类方法可以重写
- 16.5 getter和setter
- 17. 数值扩展
- 17.1 Number.EPSILON是JS最小精度
- 17.2 进制运算
- 17.3 其他
- 18. ES5-ES6对象方法拓展
- 18.1 Object.is判断两个值是否完全相等,如果是对象的话,必须是同一个引用。
- 18.2 Object.assign 对象的合并
- 18.3 Object.setPrototypeOf设置原型对象
- 19. 模块化
- 19.1 模块暴露语法汇总
- 19.1.1 分别暴露
- 19.1.2 统一暴露
- 19.1.3 默认暴露(VUE常用)
- 19.2 模块引入语法汇总
- 19.2.1 通用的导入方式
- 19.2.2 解构赋值的形式
- 19.3.3 简便形式(only默认暴露)
- 19.3 入口文件方式
- 20. ES7新特性
- 20.1 **幂运算
- 21. ES8新特性
- 21.1 async
- 21.2 await
- 21.3 async await 读取文件
- 21.4 async,await封装ajax请求
- 22. ES8对象方法拓展
- 22.1 Object.values()和Object.entries()
- 22.2 Object.getOwnPropertyDescriptors获取对象属性的描述对象
- 23. ES9
- 23.1 rest参数
- 23.2 扩展运算符
- 24. ES10新特性
- 24.1 Object.fromEntries()
- 24.2 字符串方法 trimStart()和trimEnd()
- 24.3 数组方法 flat()和flatMap()
- 24.4. 私有属性
- 24.5 Promise.Allsettled()方法
- 24.6 ==可选链操作符==
- 24.7 动态引入
- 24.8 BigInt类型
6.1 声明方法
声明一个函数:
// 一般
let fn = function(a,b){//代码体
}
// 箭头函数
let fn = (a,b) => {//代码体
}
6.2 特性
6.2.1 静态this
箭头函数的this是静态的,时钟指向函数声明时所在作用域下this的值。
function getName() {console.log(this.name)}let getName2 = () => {console.log(this.name)}window.name = '窗体对象name'const obj = {name: "一个对象的名字"}// getName(); // getName2();// 都会返回window.name// call方法调用getName.call(obj)// this被动态的改为对象getName2.call(obj)// this还是原来的窗体
另外一个例子:
需求,点击方块立刻变成粉色。
普通写法,需要将this存起来,因为function的this指向会发生改变
let ad = document.getElementById('ad')ad.addEventListener("click", function () {let _this = thislet changeColor = function () {_this.style.background = 'pink'}changeColor()})
箭头函数写法,不用存this,因为箭头函数的this是静态的,它的this就指向function的this,即名为ad的变量。
let ad = document.getElementById('ad')ad.addEventListener("click", function () {changeColor = () => {this.style.background = 'pink'}changeColor()})
6.2.2 不能作为构造函数实例化对象
个人理解是,既然this在声明时已经指向函数所在作用域下this的值,那么this就不能再重新赋值,作为一个新的对象了。(不能把窗体作为一个刚new的Person对象)
错误示例:
let Person = (name, age) => {this.name = namethis.age = age}let me = new Person('xiao', 30)console.log(me)//Uncaught TypeError: Person is not a constructor
6.2.3 不能使用arguments对象
arguments对象是在函数调用时存储形参的对象
function func1(a, b, c) {console.log(arguments[0]);// expected output: 1console.log(arguments[1]);// expected output: 2console.log(arguments[2]);// expected output: 3
}func1(1, 2, 3);
但是箭头函数没有这个对象
let fn = () => {console.log(arguments);}fn()//Uncaught ReferenceError: arguments is not defined
6.2.4 箭头函数的简写
6.2.4.1 省略小括号
当形参有且只有一个时。
let add = n =>{return n+n
}
console.log(add(9))
//18
6.2.4.2 省略花括号
当代码体只有1条语句时,此时return也必须省略,而且语句的执行结果就是函数的返回值。
let pow = n => n * n
console.log(pow(9))
6.2.4.3 案例
const arr=[1,6,9,10,100,25]
const result=arr.filter(function(item){if(item%2===0){return true}else{return false}
})
箭头函数简写:
const result = arr.filter(item=>item%2===0)
结果都是[6,10,100],都是对的。
6.2.5 箭头函数的应用场景
- 适合于this无关的回调,定时器,数组的方法回调
- 不适合与this有关的回调,事件回调,对象的方法
比如:
{name:'Sabina',getName:function(){return this.name;//可以拿到这个对象name}getName1:()=>{return this.name//这个时候的this指向的是外层作用域的this值}
}
7. 函数参数的默认值
如果不赋值,即为undefined
或者,与解构赋值结合:
function connect({host='127.0.0.1',username,pswd,port}){}
connect({host:'baidu.com',username:'root',pswd:'123456',port:3306
})
8. rest参数
ES6引入rest参数,用于获取函数的实参,用来代替arguments
- ES5获取实参的方式:
function date(){console.log(arguments)
}
date('丁小宜','丁心宜','dxy')
打印出来的arguments是一个对象
- ES6通过rest参数获取实参:
function date(...args){console.log(args)
}
date('丁小宜','丁心宜','dxy')
打印出来的是一个数组。注意,如果方法有多个参数,要把arguments放在最后。
function fn(a,b,...args){console.log(a)//1console.log(b)//2console.log(args)//[3,4,5,6]
}
fn(1,2,3,4,5,6)
9. 扩展运算符
…运算符可以将数组转换成逗号分隔的参数序列(实参)
const tfboys = ['易烊千玺','王源','王俊凯']
function chunwan(){console.log(arguments)
}
chunwan(...tfboys)
//相当于传了三个参数,而不是一个数组
9.1 扩展运算符的应用
9.1.1 数组的合并
const arr1 = [1,2,3]
const arr2 = [4,5,6]
const arr = [...arr1,arr2]
9.1.2 数组的拷贝
浅拷贝
const arr1 = [1,2,3]
const arr2 = [...arr1]
9.1.3 将维数组转换为真正的数组
const divs = document.querySelectorAll('div')
let divArr = [...divs]
console.log(divArr)
10. Symbol数据类型
一种类似于string的数据类型,但是又不同。
JS一共有7种数据类型,分别为USONB:
- U:undefined
- S:String Symbol
- O:Object
- N:Number Null
- B:boolean
10.1 Symbol的创建
// 构造函数
let s0 = Symbol()
let s1 = Symbol('1')
let s2 = Symbol('1')
console.log(s1===s2)//false
// Symbol.for创建
let s3 = Symbol.for('1')
let s4 = Symbol.for('1')
console.log(s3===s4);//true
10.2 向对象中添加Symbol类型的属性
let game = {name: "狼人杀",[Symbol('say')]: function () {console.log('我可以发言')},[Symbol('explotion')]: function () {console.log('我可以自爆')}}console.log(game);
打印的game:
或者添加同名方法:
let game = {name: "俄罗斯方块",up: function () {},down: function () { }}let methods = {up: Symbol(),down: Symbol()}game[methods.up] = function () {console.log('我可以改变形状');}game[methods.down] = function () {console.log('我可以快速下降');}console.log(game);
打印结果:
10.3 Symbol的内置属性
这些内置属性是Symbol的属性,同时Symbol.xx又作为对象的属性存在,目的是为了扩展对象的功能。
10.3.1 Symbol.hasInstance 对象类型检测
用于类型检测,检测某个对象是否是某个自定义类的实例,以此来控制instanceof的值。下面这个例子可以判断某个参数是否为非空数组:
class Arr1 {static [Symbol.hasInstance](instance) {return Array.isArray(instance) && instance.length > 0}}console.log([] instanceof Arr1)
10.3.2 Symbol.isConcatSpreadable
Symbol.isConcatSpreadable是一个布尔值属性,表示该对象用于Array.prototype.concat()时,是否可以展开。
const arr1 = [1, 2, 3]const arr2 = [4, 5, 6]arr2[Symbol.isConcatSpreadable] = falseconsole.log(arr1.concat(arr2));// expected [1,2,3,[4,5,6]]
11. 迭代器
为不同的数据结构提供统一的访问机制,任何数据只要部署了Iterator接口,就可以完成遍历操作。
- Iterator接口主要供for…of消费
- 原生具备Iterator接口的数据:
Array,arguments,Set,Map,String,TypedArray,NodeList - 工作原理:
const xiyou = ['1', '2', '3', '4']// 创建一个指针对象,指向当前数据结构的起始位置let iterator = xiyou[Symbol.iterator]()// 第一次调用next方法,指针自动指向数据结构的第一个成员// 之后的每一次调用next方法指针一直向后移动,直到指向最后一个成员console.log(iterator.next());console.log(iterator.next());console.log(iterator.next());console.log(iterator.next());console.log(iterator.next());
可以看到,每次调用next方法都会返回一个包含value和done属性的对象。
也可以通过对象遍历对象中的数组,而不是直接遍历,体现了面向对象的思想:
const katzchen = {name: '猫猫',stus: ['心心','心宜','丁心宜','dxy'],[Symbol.iterator]() {let index = 0return {next: () => {if (index < this.stus.length) {const result = { value: this.stus[index], done: false }index++return result}else {return { value: undefined, done: true }}}}}}for (item of katzchen) {console.log(item)}
打印结果:
12. 生成器函数
生成器可以和迭代器配合使用来解决回调地狱的问题。
12.1 生成器函数的声明与调用
- 声明
// 1
function * fnName(){}
// 2
function* fnName(){}
// 3
function *fnName(){}
// 4
function*fnName(){}
- 调用:
function* gen() {yield '一只没有耳朵'console.log(111);yield '一只没有尾巴'console.log(222);yield '真奇怪'console.log(333);}let iterator = gen()iterator.next()iterator.next()iterator.next()iterator.next()//expected output:111 222 333
yield
可以将函数分割成n+1段
12.2 next方法
- 打印next方法,每次执行next只会执行到这个next对应的yield语句,不会再继续向下执行。
function* gen() {yield '一只没有耳朵'// 第1个next()执行到这里console.log(111);yield '一只没有尾巴'// 第2个next()执行到这里console.log(222);yield '真奇怪'// 第3个next()执行到这里console.log(333);}// 第4个next()执行到这里let iterator = gen()console.log(iterator.next())console.log(iterator.next())console.log(iterator.next())console.log(iterator.next())
输出:
- next方法可以传入实参并获取
function* gen(arg) {console.log(arg);}let iterator = gen('AAA')console.log(iterator.next())
12.3 yield理解
当调用 next
方法时,开始执行,遇到 yield
表达式,就暂停后面的操作,将 yield
后面的表达式的值,作为返回的对象的 value
值.
以下示例会实现每隔一秒分别打印三个不同的数据的功能:
function getUsers() {setTimeout(() => {let data = '用户数据'// next实参将作为第一个yield语句的返回结果iterator.next(data)}, 1000)}function getOrders() {setTimeout(() => {let data = '订单数据'iterator.next()}, 1000)}function getGoods() {setTimeout(() => {let data = '商品数据'iterator.next()}, 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()
13. Promise
用来解决地狱回调的问题。
13.1 Promise的基本使用
Promise对象构造函数的参数是一个方法,提供了两个函数resolve
和reject
,这两个参数谁放在前面,如果被执行就直接return,不会再继续向下执行。
const p = new Promise(function (resolve, reject) {setTimeout(function () {let success = '数据读取成功';//设置Promise对象状态为成功resolve(success)let err = '数据读取失败'//设置Promise对象状态为失败reject(err)}, 1000)})// Promise对象的then方法里面的两个参数也是两个匿名方法,分别是成功和失败的参数。p.then((value) => {console.log(value);}, (reason) => {console.log(reason);})
13.2 Promise读取文件
// 1.引入fs模块
const fs = require('fs')
// 2.调用方法读取文件
// fs.readFile('./ES6.md', (err, data) => {// if (err) throw err
// console.log(data.toString());
// })
// 3.使用Promise封装
const p = new Promise(function (resolve, reject) {fs.readFile('./ES6.md', (err, data) => {if (err) reject(err);resolve(data)})
})
p.then(value => console.log(value.toString()), reason => console.log('读取失败',reason))
13.3 Promise封装AJAX请求
封装前:
// 创建对象const xhr = new XMLHttpRequest();// 初始化xhr.open('GET', 'https://api.apiopen.top/getJoke')// 发送xhr.send()// 绑定事件,处理相应结果xhr.onreadystatechange = () => {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', 'https://api.apiopen.top/getJoke')// 发送xhr.send()// 绑定事件,处理相应结果xhr.onreadystatechange = function () {// console.log(xhr);if (xhr.readyState === 4) {if (xhr.status >= 200 && xhr.status < 300) {resolve(xhr.response)} else {reject('请求失败');}}}})p.then(function (value) {console.log(value)},function (reason) {console.log(reason)})
扫盲:
XMLHttpRequest.readyState
属性返回一个 XMLHttpRequest
代理当前所处的状态。一个 XHR 代理总是处于下列状态中的一个:
所以同一次请求可能在不同的时刻经历过XMLHttpRequest.readyState===2,3,4的情况。所以这个自定义属性不应该写成这样:
xhr.onreadystatechange = function () {// console.log(xhr);if (xhr.readyState === 4) {if (xhr.status >= 200 && xhr.status < 300) {resolve(xhr.response)} }else {reject('请求失败');}}
这样会打印出两个请求失败和一个成功后的response。
- XMLHttpRequest的MDN : https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest
13.4 then方法
13.4.1 返回的Promise对象的状态
调用then方法,返回值的promise对象的值就是return的值(或是Promise的参数)
- 如果回调函数返回的是非Promise类型的数据,状态为成功
- 如果是Promise对象,看对象的状态,如果为resolve则为成功,如果为reject则为失败
- 如果抛出错误则Promise对象状态一定是失败
三种情况的示例:
const p = new Promise((resolve, reject) => {setTimeout(() => {resolve('用户数据')}, 2000)})let result = p.then(value => {console.log(value)// 1. 非Promise类型// return 123;// 2. Prmise类型// return new Promise((resolve,reject)=>{// resolve('ok')// reject('error')// })// 3.抛出错误// throw '出错啦!'}, reason => {console.warn(reason)})console.log(result);
13.4.2 链式调用
then支持链式调用:
p.then((value)=>{},reason=>{}).then((value)=>{},reason=>{})
13.5 catch方法
其实是一个语法糖,相当于then不实现参数中成功的方法。
const p = new Promise((resolve, reject) => {setTimeout(() => {reject("出错啦!")}, 1000)})p.catch(reason => {console.log(reason);})// 相当于// p.then(_, reason => console.log(reason))
14. Set
一个数据类型,不包括重复的元素,是Objet
基本用法:
// 声明let s = new Set(['大事儿', '小事儿', '好事儿', '坏事儿', '小事儿'])console.log(s);// ['大事儿', '小事儿', '好事儿', '坏事儿']// 添加新元素s.add('111')// 删除元素s.delete('坏事儿')// 检测s.has('好事儿')// 清空s.clear()// 遍历for(let v of s){console.log(v);}
15. Map
一个数据类型,包括键值对,是Objet,其中key可以是任何数据类型
- size 返回Map的元素个数
- set 增加一个新元素,返回当前Map。如:(m.set(‘key’,‘value’))
- get 返回键名对象的键值
- has 检测map中是否含有某个元素,返回boolean
- clear清空集合,返回undefind
16. class类
通过class关键字,可以定义类。这是ES6引入的更加面向对象编程的语法,但是他的大多数功能ES5也可以实现。
16.1 class声明类
// ES5声明类function Phone(brand, price) {this.brand = brandthis.price = price}Phone.prototype.call = function () {console.log('我可以打电话!');}// 注意,如果不加prototype则是在函数上直接添加属性,在实例化的时候对象不会有这个属性// 我们称他为静态属性let Huawei = new Phone('华为', 5999)Huawei.call()console.log(Huawei);// ES6声明类class Shouji {// 构造方法,在new的时候就会执行这个实例对象上的constractor方法constructor(brand, price) {this.brand = brandthis.price = price}//方法必须这样写,不能使用ES5的对象完整形式call() {console.log('我也可以打电话~');}}let OnePlus = new Shouji("1+", 1999)OnePlus.call()console.log(OnePlus);
16.2 constractor定义构造函数初始化
ES5实现继承:
function Phone(brand, price) {this.brand = brandthis.price = price}Phone.prototype.call = function () {console.log('我可以打电话');}function smartPhone(brand, price, color, size) {Phone.call(this, brand, price)this.color = colorthis.size = size}// 设置子级构造函数的原型smartPhone.prototype = new Phone// 这行可以不加,不加的话子类就没有原型了smartPhone.prototype.constructor = smartPhone//声明子类的方法smartPhone.prototype.photo = function () {console.log('我可以拍照');}const xiaomi = new smartPhone('小米', 3999, 'blue', '5.1inch')console.log(xiaomi);xiaomi.call()xiaomi.photo()
打印结果:
16.3 extends继承父类,super调用父级构造方法
ES6实现类继承:
class Phone {constructor(brand, price) {this.brand = brandthis.price = price}call() {console.log('我可以打电话');}}class SmartPhone extends Phone {constructor(brand, price, color, size) {// 相当于// Phone.call(this,brand,price)super(brand, price)this.color = colorthis.size = size}photo() {console.log('我可以拍照');}playGame(){console.log('我可以玩游戏');}}const xiaomi = new SmartPhone('小米', 3999, 'blue', '5.1inch')console.log(xiaomi);xiaomi.call()xiaomi.photo()
16.4 父类方法可以重写
子类直接在方法里面写父类同名方法就可以实现父类方法的重写,不再赘述。
16.5 getter和setter
class Phone {get price() {console.log('价格属性被读取了');return '520'}set price(newVal) {console.log('价格属性被修改了');}}let s = new Phone()console.log(s.price);s.price = 'free'
17. 数值扩展
17.1 Number.EPSILON是JS最小精度
function equal(a, b) {return Math.abs(a - b) < Number.EPSILON ? true : false}console.log(0.1 + 0.2 === 0.3);//falseconsole.log(equal(0.1 + 0.2, 0.3));//true
17.2 进制运算
- 2进制:0b开头
- 8进制:0o开头
- 16进制:0x开头
17.3 其他
- Number.trunc:将数字的小数部分抹掉
- Math.sign 判断一个数是正数(return 1)负数(return -1)还是0(return 0)
18. ES5-ES6对象方法拓展
18.1 Object.is判断两个值是否完全相等,如果是对象的话,必须是同一个引用。
Object.is('foo', 'foo'); // true
Object.is(window, window); // trueObject.is('foo', 'bar'); // false
Object.is([], []); // falsevar foo = { a: 1 };
var bar = { a: 1 };
Object.is(foo, foo); // true
Object.is(foo, bar); // falseObject.is(null, null); // true// 特例
Object.is(0, -0); // false
Object.is(0, +0); // true
Object.is(-0, -0); // true
Object.is(NaN, 0/0); // true
Object.is(NaN,NaN) // true
18.2 Object.assign 对象的合并
Object.assign(Object1,Object2)
如果属性两个对象存在同名属性,则会用Object2的属性覆盖Object1的属性。不同名的互不覆盖。
18.3 Object.setPrototypeOf设置原型对象
const school = {name: '山东大学'}const cities = {xiaoqu: ['济南', '威海', '青岛']}// 设置school的原型为citiesObject.setPrototypeOf(school, cities);console.log(school);// 获取原型console.log(Object.getPrototypeOf(school));
19. 模块化
通过模块化,可以提高项目的复用性,降低维护成本等。
19.1 模块暴露语法汇总
19.1.1 分别暴露
export let school = '山东大学'
export let geli = function(){console.log('隔离中')
}
19.1.2 统一暴露
let school = '山东大学'
let geli = function(){console.log('隔离中')
}
export {school,geli}
19.1.3 默认暴露(VUE常用)
export default{school:'山东大学',geli:function(){console.log('隔离中')}
}
19.2 模块引入语法汇总
19.2.1 通用的导入方式
import * as m1 from "./src/m1.js"
19.2.2 解构赋值的形式
这种形式可以直接使用school
和geli
这两个变量。
import {school,geli} from "./src/m1.js"
如果有重名的变量,可以使用别名的方式:
import {school,geli} from "./src/m1.js"
import {school as university} from "./src/m2.js"
对于默认暴露,这里引入的是default
属性的变量,但是不能直接使用default
,必须起一个别名采用如下固定格式:
import {default as m3} from "./src/m3.js"
19.3.3 简便形式(only默认暴露)
只针对默认暴露!!
import m3 from "./src/m3.js"
19.3 入口文件方式
使用入口文件进行引入(app.js),然后在html中引用:
<script src="./../js/app.js" type="module"></script>
20. ES7新特性
20.1 **幂运算
console.log(2**10)//1024
21. ES8新特性
21.1 async
会返回一个promise对象,对象的状态取决于return的值:
- 若返回的结果不是一个Promise类型的对象,则async函数返回的promise对象的状态都是resolved.
- 抛出错误的话Promise对象的状态为rejected.
- 若返回的结果是一个Promise类型的对象,取决于返回的Promise对象的状态.
async function fn() {return new Promise((resolve, reject) => {// resolve('成功的数据')reject('失败的数据')})}const result = fn();console.log(result);
如果调用then,则then调用的回调函数取决于Promise的状态.
21.2 await
await必须写在async函数中,其右测表达书一般为primise对象,返回的是promise成功的值,如果promise失败了就会抛出异常,需要通过try…catch处理.
const p = new Promise((resolve, reject) => {// resolve('成功啦!')reject('失败啦!')})async function main() {try {let result = await pconsole.log(result);} catch (e) {console.log(e);}}main()
21.3 async await 读取文件
let fs = require('fs')function readMd() {return new Promise((resolve, reject) => {fs.readFile("./../md/ES6.md", (err, data) => {if (err) reject(err)resolve(data)})})
}
async function main() { let data = await readMd()console.log(data.toString());
}
main()
21.4 async,await封装ajax请求
首先用promise对AJAX请求进行封装:
function sendAJAX(url) {let xml = new XMLHttpRequest()xml.open('get', url)xml.send()return new Promise((resolve, reject) => {xml.onreadystatechange = function () {if (xml.readyState === 4) {if (xml.status >= 200 && xml.status < 300) {resolve(xml.response)} else {reject(xml.status)}}}})}
调用then方法:
const result=sendAJAX('https://api.apiopen.top/getJoke').then(res=>console.log(res),err=>console.log(err))
或者使用async&await:
async function main() {let result = await sendAJAX("https://api.apiopen.top/getJoke")console.log(result);}main()
都可以打印响应体或者失败的状态码.
22. ES8对象方法拓展
首先创建一个对象:
const school = {name: '山东大学',cities: ['济南', '威海', '青岛'],xueke: ['理科', '工科', '文科']}
22.1 Object.values()和Object.entries()
应用实例,注意2,3是ES8的新特性
// 1.获取对象所有的键console.log(Object.keys(school));// 2.获取对象所有的值console.log(Object.values(school));// 3.entries:获取键值console.log(Object.entries(school));// 4.创建mapconsole.log(new Map(Object.entries(school)));
打印结果:
22.2 Object.getOwnPropertyDescriptors获取对象属性的描述对象
console.log(Object.getOwnPropertyDescriptors(school));
打印结果:
23. ES9
23.1 rest参数
rest参数可以将函数实参中剩下的参数存到一个对象里,例如
function connect({ host, port, ...user }) {console.log(host);console.log(port);console.log(user);}connect({host: '127.0.0.1',port: 3306,username: 'dxy',password: '123456'})
23.2 扩展运算符
可以实现对象的合并.
const lifeOne = {o: '吃饭'}const lifeTwo = {t: '睡觉'}const lifeThree = {c: '写代码'}const life = { ...lifeOne, ...lifeTwo, ...lifeThree }console.log(life);// {o: '吃饭', t: '睡觉', c: '写代码'}
24. ES10新特性
24.1 Object.fromEntries()
可以将二维数组或Map转换成对象
// 二维数组,将二维数组转化为对象let arr = [['school', '山东大学'], ['compus', '软件学院,微电子学院']]const result = Object.fromEntries(arr)console.log(result);// Mapconst m=new Map()m.set('school','山东大学')m.set('compus','软件学院,微电子学院')console.log(Object.fromEntries(m));
和Object.entries()互为逆运算
// 二维数组,将二维数组转化为对象let arr = [['school', '山东大学'], ['compus', '软件学院,微电子学院']]const result = Object.fromEntries(arr)console.log(result);// 对比Object.entries()const arr1 = Object.entries(result)console.log(arr1);
24.2 字符串方法 trimStart()和trimEnd()
let str=' iloveyou 'console.log(str);
// 去掉开头空格
console.log(str.trimStart());
// 去掉结尾空格
console.log(str.trimEnd());
// 去掉所有空格
console.log(str.trim());
24.3 数组方法 flat()和flatMap()
flat()可以将数组从高维转为低维,默认参数是1,即维度-1,如果不是1则需要填写参数,参数为目前维度-目标维度
,是一个Number。
map()方法如果返回的是一个高维数组,也可以使用flatMap()将Map()转化成一个低维数组。
24.4. 私有属性
在类的前面加#即可制定这个属性为私有属性
,这个属性不能在对象中直接调用,要通过类的方法调用这个对象的私有属性,体现了面向对象的思想。
class Person {name;#age;#weight;constructor(name, age, weight) {this.name = namethis.#age = agethis.#weight = weight}get() {console.log(this.name);console.log(this.#age);console.log(this.#weight);}}const girl = new Person('小红', 21, '50kg')// 通过类的方法打印才能打印出来girl.get()// console.log(girl.#age);// Uncaught SyntaxError: Private field '#age' must be declared in an enclosing class
24.5 Promise.Allsettled()方法
可以一次接收多个Promise对象(用数组排列),无论每一个Promise结果如何,其返回的Promise总是resolved,和all不一样,all只在每一个Promise都为resolved时候返回的才是才是resolve。
24.6 可选链操作符
可以用?.
代替&&
进行链式判断,举一个传参的例子,如果我们行要访问对象的某个参数,首先需要检验它在不在,如果不在会返回undefined,不会报错:
function main(config) {//相当于 const dbHost = config && config.db && config.db.host;const dbHost = config?.db?.host;console.log(dbHost);}main({db: {host: '192.127.1.100',username: 'root'},cache: {host: '192.127.1.200',username: 'admin'}})//192.127.1.100
24.7 动态引入
使用import()动态引入另一个模块,返回的是一个promise对象,只需要调用这个对象的方法即可。
举例:
第一步:在html中引入app.js,添加按钮写id:
<body><button id="btn">点击</button><script src="./../js/app.js" type="module"></script></body>
第二步:在app.js获取id:
const btn = document.getElementById('btn')
第三步:在btn.js写一个点击事件和方法并暴露出去:
export function hello() {alert('Hello')
}
第四步:在app.js动态引入并使用btn.js的函数:
btn.onclick = function () { import('./btn.js').then(module => {module.hello()})
}
点击按钮就会触发alert事件:
24.8 BigInt类型
用处不多,主要注意声明的时候在数字后面加n就会检测出是bigint类型了,而且两个BigInt不能喝Number运算,只能和BigInt运算。
ES6学习笔记(包括ES6-ES11常用特性)相关推荐
- Vue学习笔记(一)—— 常用特性
简介 Vue的常用特性其实也是Vue语法的一部分,只是为了学习方便,所以单独拿出来进行说明,学习上也显得更清晰. 对于基础部分,可用参考官网上的介绍. Vue 常用特性 表单操作 自定义指令 计算属性 ...
- ES6学习笔记二arrow functions 箭头函数、template string、destructuring
接着上一篇的说. arrow functions 箭头函数 => 更便捷的函数声明 document.getElementById("click_1").onclick = ...
- es6学习笔记-字符串的扩展_v1.0_byKL
es6学习笔记-字符串的扩展_v1.0 字符的Unicode表示法 JavaScript 允许使用uxxxx的形式表示一个字符,但在 ES6 之前,单个码点仅支持u0000到uFFFF,超出该范围的必 ...
- ES6学习笔记03:变量的解构赋值
ES6学习笔记03:变量的解构赋值 如果想从复杂数据结构(数组.对象)中获取某一个数据,可能需要大量的遍历操作才能完成.通过解构赋值,这一过程可以得到简化. 1.字符串的解构赋值 其实,Python也 ...
- ES6学习笔记02:let 与 const
ES6学习笔记02:let 与 const 用var声明的变量会造成全局污染,于是就产生了新的声明方式. 1.let 用let声明变量,必须先声明后使用. 在for循环头里用let定义循环变量i,那么 ...
- ES6学习笔记01:Symbol数据类型
ES6学习笔记01:Symbol数据类型 1.Symbol定义 浏览demo01.html: 2.Symbol作对象属性名 Symbol函数可以接收一个字符串作为参数,表示对Symbol实例的描述,输 ...
- # es6 学习笔记
es6 学习笔记 let变量 let和var用法级别一样 let不能重复声明,但是var可以 var varIns = "A"; var varIns = "B" ...
- ES6学习笔记(五):轻松了解ES6的内置扩展对象
前面分享了四篇有关ES6相关的技术,如想了解更多,可以查看以下连接 <ES6学习笔记(一):轻松搞懂面向对象编程.类和对象> <ES6学习笔记(二):教你玩转类的继承和类的对象> ...
- ES6学习笔记(三):教你用js面向对象思维来实现 tab栏增删改查功能
前两篇文章主要介绍了类和对象.类的继承,如果想了解更多理论请查阅<ES6学习笔记(一):轻松搞懂面向对象编程.类和对象>.<ES6学习笔记(二):教你玩转类的继承和类的对象>, ...
- ES6学习笔记04:Set与Map
ES6学习笔记04:Set与Map JS原有两种数据结构:Array与Object,ES6新增两种数据结构:Set与Map 一.Set数据结构 Set类似于数组,但是成员值不允许重复,因此主要用于数据 ...
最新文章
- 《lua程序设计(第二版)》学习笔记(五)-- 函数基础
- pl/sql dev连接报错Access violation at address 67614F04 in module 'oranls11.dll'
- 微信小程序浮动按钮_操作按钮悬浮固定在微信小程序底部的实现代码
- Testin云测试:QQ(4.2.0)安卓版客户端可用性优秀
- mysql的原理图解_MySQL排序工作原理
- IT牛人往事如烟之七大“先烈”
- LeetCode刷题: 整数反转
- android 获取和设置屏幕亮度
- java如何脱离ide运行_如何脱离IDE使用自己的jar包?
- python日志处理三方工具loguru与常用场景快捷配置
- 关于HTML静态页面(含自动分页)生成的可行性方案
- Android在WindowManagerService和ActivityManagerService中的Token
- 小D课堂 - 新版本微服务springcloud+Docker教程_5-06 高级篇幅之深入源码
- ug建模和草图切换_从草图到XD,为什么我要切换
- 机器人应用(Skill)精选丨让HEXA机器人成为直播网红,还可以接收红外信号
- 图的深度优先遍历java代码详解
- std::adjacent_find 用法
- 赫夫曼压缩解压(java)
- 简单几个步骤,通过github搭建浪漫的表白网页
- Advanced Practices:一款新型恶意监测工具的改进过程