1. 查看浏览器兼容性: http://kangax.github.io/compat-table/es6
不兼容需要安装babel
2. 块作用
// for
for(var i = 0; i < 3; i++) {
item[i].onclick = () => {} // 报错: 越狱
}
for(let i = 0; i < 3; i++) {
item[i].onclick = () => {}
}
// let
1.变量不能重复定义
2.不存在变量提升,只在当前作用域访问
3.先声明后使用
// const
1.定义即赋值, -----------------!只读常量!
2.变量名为大写
3.不能重新赋值, 但是可以改变对象、数组, 就是不能出现赋值操作
const ARR = [1, 2]
ARR = [1] // ERROR
ARR.push(3) // 这种改变OK
赋值 实在内存中开辟一块空间来存放变量
4.只能在当前作用域访问
// 解构的目的是: 从对象或数组中提取值, 对变量赋值
// 数组解构
const ARR1 = [1, 2, 3]
let [age1, age2, age3] = ARR1
log(age1, age2, age3)
// 解构默认值 静态动态
const ARR1 = [1, , 3]
let [age1, age2:10, age3] = ARR1
log(age1, age2, age3) // 1, 10, 3
let [age1, age2:age3, age3] = ARR1 // 报错
let [age1, age2:age1, age3] = ARR1 // OK
// 函数参数有默认值 必须放最后!! 且arguments length失效
function add(a=0,b=0, c=0) {
return a + b + c
}
add()
add(1, 2, 3)
console.log('add()', add(), add(1, 2, 3 ))
// 函数参数使用rest参数 必须放最后!!
function aFn(...rest) {
console.log(rest, ...rest)
}
aFn(1,2,3) // [1, 2, 3] 1, 2, 3
// 函数参数与解构赋值结合
function add({ a, b, c=0 } = {a: 0, b: 0}) {
return a + b + c
}
add()
add({a:1, b:2})
console.log('add()', add(), add({a:1, b:2}))
// 拓展运算符... 合并数组(concat) 数组深克隆 伪数组转数组
const Arr5 = ['tom1', 'tom2']
const Arr6 = [...Arr5, 'tom3']
console.log('数组合并', Arr6)
const Arr7 = [...Arr5]
console.log('arr7-5改之前', Arr7)
Arr5.push('tom')
console.log('改了Arr5数组增长一位看看Arr7受影响不', Arr5, Arr7)
// ["tom1", "tom2", "tom"] ["tom1", "tom2"]
let dom2 = document.getElementsByClassName('block')
// dom2.pop() // 报错 不能用数组方法 -> 不是数组
console.log('dom2', dom2)
let domArr = [...dom2]
domArr.pop() // ok
console.log('domArr', domArr)
// 对象解构
// 模板字符串 有换行 有拼接时
`${a+b}`
// 箭头函数 this为静态指向 不会改变
// 适合做跟this无关的回调 定时器 数组方法
// 不适合做跟this有关的回调 dom操作回调 对象方法的回调
let fn1 = () => {
// 箭头函数的作用域在定义时就确定了, 定义在全局就是全局的, 不受call/apply影响
log(this.name)
}
function fn2() {
log(this.name)
}
window.name = 'window-tom'
const USERNAME = {
name: '局部-tom',
// fn1,
// fn2,
}
// log(USERNAME.fn1(), USERNAME.fn2()) // window-tom 局部-tom
fn1.call(USERNAME) // 据说还是全局 我打印出来的是undefined
fn2.call(USERNAME)
//静态指向不可改变,所以不能用构造函数,不能用arguments
let fn3 = function() {
console.log('arguments', arguments)
}
let fn4 = () => {
console.log('arguments', arguments)
// let.html:208 Uncaught ReferenceError: arguments is not defined
}
fn3(1, 2)
fn4(1, 2)
// this的应用
let dom1 = document.getElementsByClassName('pink')[0]
console.log('dom', dom1, dom1[0])
// dom1.addEventListener('click', function() { // ok
// setTimeout(() => {
// this.style.background = 'red'
// }, 2000)
// })
// dom1.onclick = () => { // 从这开始 this就变质了 this原来指向dom1 用了箭头就变成了当前作用域下的了
// setTimeout(() => {
// this.style.background = 'red'
// }, 2000)
// }
dom1.onclick = function() { // ok 找作用域要从变量最深层开始
setTimeout(() => {
this.style.background = 'red'
}, 2000)
}
域由 { } 包括,if语句和for语句里面的{ }也属于块作用域。
新增es6基本类型:Symbol 防止属性名重复,不能进行运算
let s = Symbol()
console.log('s', s, typeof s) // Symbol 'symbol'
let s1 = Symbol('Tom')
let s4 = Symbol('Tom')
console.log('s1', s4 === s1) // false
let s2 = Symbol.for('tom1')
let s3 = Symbol.for('tom1')
console.log('s3', s2 === s3) // true
for(let item in [{age: 1}]) {
console.log('item-in', item) // 0
}
for(let item of [{age: 1}]) {
console.log('item-of', item) // 当前key
}
迭代器: 数组 map set
生成器:
-------------------------------实现 2s后打印1 再2s后打印2 再2s后打印3
setTimeout(function(){
log(1)
setTimeout(function(){
log(2)
setTimeout(function(){
log(3)
}, 2000)
}, 2000)
}, 2000)
-------------------------------- 改写:生成器函数
function one() {
setTimeout(function(){
log(1)
iterator.next() // 返回数据 iterator.next(data)
}, 2000)
}
function two() {
setTimeout(function(){
log(2)
iterator.next()
}, 2000)
}
function three() {
setTimeout(function(){
log(3)
iterator.next()
}, 2000)
}
function * gen() {
yield one() // 返回数据 let onedata = yield one() log(onedata)
yield two()
yield three()
}
let iterator = gen()
iterator.next()
// promise 题锦
// 0.
let title = null
let p1 = new Promise((resolve, reject) => { //
log('立即执行内部的同步方法!!')
reject('error')
resolve('success')
log('上面没return,我就会被执行')
}).then(function (value) {
// 调用then方法 then方法的返回结果是Promise对象, 对象状态由回调函数的执行结果决定
// 1.如果回调函数的返回结果是非promise类型的属性, 状态即为成功, 返回值为对象的成功状态
// 2.---------------------是------------------------由内部执行结果决定
console.log('成功返回数据', value)
title = value
}, function (reason) {
console.log('失败返回数据', reason)
title = reason
}).finally(res => {
console.log('finally', `我都${title}了你不说两句`)
})
// 1.执行顺序
// resolve前不加return
const p = new Promise((resolve, reject) => {
resolve('3')
console.log('0')
let ab,cd
ab = 1
cd = 2
console.log('1', ab, cd)
})
console.log('2', p) // 0 1 2 3
// 加return
const p = new Promise((resolve, reject) => {
return resolve('3') // 后面不执行
console.log('0')
let ab,cd
ab = 1
cd = 2
console.log('1', ab, cd)
})
console.log('2', p) // 2 3
console.log('--------------------------------测试: setTimeout promise 执行顺序');
console.log('1setTimeout上面');
setTimeout(() => {
console.log('7setTimeout内部');
}, 3000)
console.log('2Promise上面');
const p6 = new Promise((resolve, reject) => {
console.log('3Promise内部')
resolve('Promise-resolve')
console.log('4Promise内部最后一行')
})
console.log('5Promise下面', p6)
console.log('6完毕~')
--------------------------------- Promise 比 定时器 的执行优先级更高
setTimeout(function () { // setTimeout(fn, 0)在下一轮“事件循环”开始时执行
console.log('three');
}, 0);
Promise.resolve().then(function () {
// 执行时机: 上面代码中,setTimeout(fn, 0)在下一轮“事件循环”开始时执行,Promise.resolve()在本轮“事件循环”结束时执行,console.log('one')则是立即执行,因此最先输出
console.log('two');
});
console.log('one');
// one
// two
// three
// 2.嵌套调用
// 通过then方法把多个异步串联起来
const fs = require('fs')
const q = new Promise((resolve, reject) => {
fs.readFile('./为学.md', (err, data) => {
resolve(data)
})
})
q.then(value => {
console.log('第一次调用返回结果', value.toString())
return new Promise((resolve, reject) => {
fs.readFile('./插秧诗.md', (err, data) => {
resolve([value.toString(), data.toString()])
})
})
}).then(value => {
console.log('第二次调用返回结果', value)
return new Promise((resolve, reject) => {
fs.readFile('./木头诗.md', (err, data) => {
resolve([...value, data.toString()])
})
})
}).then(value => {
console.log('第三次调用返回结果', value)
})
// 3. catch 捕获promise内部异常
const cp = new Promise((resolve, reject) => {
setTimeout(() => {
reject("错误了")
}, 1000)
})
cp.then(value => {
console.log('value', value)
}//, reason => {
// console.log('reason', reason)
// }
).catch(error => { -打印报错
console.log('error', error);
})
new Promise(function(resolve, reject){
})
法一:.then(function() {} // , function() {})
法二:.then(function(res)).catch(function(err){}) // catch还能捕捉promise内部err
状态不可逆,成功或失败,状态不变,不往下执行也不重新执行:
一旦失败就不会成功了
let p = new Promise(function(resolve, reject) {
fs.readFile('./resource/为学.md', (err, data) => {
if (err) reject(err)
resolve(data)
log('hi') // 会打印出来
// return resolve(data) 后面的同步操作就不会执行了
})
})
p.then(function (value) {
console.log('成功:', value.toString()) // --- 状态不可变-> 回调会重新执行!!!
}, function (reason) {
console.log('失败:', reason)
})
p.then(function (value) {
console.log('成功1:', value.toString())// --- 状态-> 返回结果是一样
}, function (reason) {
console.log('失败1:', reason)
})
for in 遍历的是index
for of 遍历的是value 基本用在数组身上
---------------------Set
新的数据结构Set: 是个对象 但是成员值都是唯一的
用途: 去重
console.log('一个简单的数组')
const oArr = new Set([8, 9, 1])
const arr = [1, 2, 3, 3, 2, 1]
const result = [...new Set(arr)]
// const rArr =result.filter(item => oArr.indexOf(item) > 0)
const rArr =result.filter(item => oArr.has(item) > 0)
console.log('取俩数组的交集-去重+filter', rArr)
const b1 = [1, 2, 4]
const b2 = [2, 5, 3]
const b3 = [...new Set([...b1, ...b2])]
console.log('取俩数组的并集', b3)
Set: 类似数组的对象 成员都是唯一的
add(single) delete() size() has() clear()
Map: 打破以往的键只能是string类型
set() get() delete() size() has() clear()
keys() values() entries() forEach()
function Phone() {// 构造函数对象
}
Phone.name = 'huawei' // 实例对象
Phone.price = 3999
const ph1 = new Phone() // 实例对象属性 跟 构造函数原型对象的属性 是相通的
console.log('ph1.name', ph1.name)
class Shouji {
static name = '手机' // static 标志的类 属于Shouji 不属于实例出来的对象
static change() {
console.log('改变世界')
}
}
const shouji = new Shouji()
console.log('shouji', shouji.name) // undefined
console.log('shouji', Shouji .name) // 手机
-------------------------es7
1.数组方法:indexOf new Set().has()
数组内是否含有某元素 .includes()
2.幂运算:
2 ** 2
-------------------------es8
1.async await
async函数返回 promise对象,外部可以使用.then方法,内部可以有异步方法用await命令,表明 async函数遇到await 直接返回,等待await命令后的函数执行完毕后,再回来执行
const fn1 = new Promise((resolve, reject) => {
// resolve('成功了了了')
reject('失败') ----> 用trycatch 捕获异常
})
async function clq() {
try {
const Fn = await fn1
console.log('Fn', Fn)
return Fn
} catch (error) {
console.log('error', error)
}
}
clq()
2.拓展方法:
// 数组方法的拓展
// spread 拓展运算符
// Array.from() 类似数组的转数组
// Array.of(11,2) 一组值转成数组
// [].keys() .values() .entries()
// [].flat() 默认拉平一层 [].flat(Infinity) 无论多少层都拉成一维数组 .flatMap() 俩方法,只一层
// .includes() 数组中是否包含某值
// 对象的方法
// spread 拓展运算符
// super 指当前对象的原型对象
// 对象的拓展方法
// Object.assign() 合并
// Object.is() 判断对象是否相等
// Object.keys() .values() .entries()
// Object.fromEntries([[key, value],[key, value]]) 键值对转换成对象
// Object.getOwnPropertyDescriptors() 获取对象每个key的描述属性
// 对象拓展运算符 rest参数
function read({name, ...user}) {
console.log(name, user.age)
}
read({name: 'tom', age: 12})
const obj1 = {
name: 'tom2'
}
const obj11 = {
name: 'tom3'
}
const obj112 = {
age: '12'
}
console.log('spread-obj1', {...obj1, ...obj11, ...obj112})
es11:
class的私有属性: #age
动态导入:import('./').then(modules => { modules.方法属性...})
globalThis: 全局this node: global 浏览器是window
bigInt(整数)