ECMAScript

本文深入探讨了ES6中的核心特性,包括块级作用域(let, const)、解构赋值在数组和对象中的应用、箭头函数的this绑定规则以及如何处理异步操作的Promise。还介绍了模板字符串、Symbol、生成器以及函数参数的默认值和rest参数。通过实例解析了这些新特性的使用方法和注意事项,帮助开发者更好地理解和利用ES6提高代码质量。
摘要由CSDN通过智能技术生成

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(整数)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值