跟着B站学前端之ES6学习笔记,涵盖ES6-ES11

ES全称ECMAScript,是脚本语言的规范。为什么要学习ES6?
1、语法简洁,功能方法
2、框架开发与应用
3、前端求职的必备技能

1、let、const

let 定义变量
  1. 变量不能重复声明
  2. 块级作用域
  3. 不存在变量提升
  4. 不影响作用域链
const 定义常量
  1. 一定要赋初始值 (不然会报错:SyntaxError: Missing initializer in const declaration)
  2. 一般常量使用大写(语法规则)
  3. 常量的值不能修改(不然会报错:TypeError: Assignment to constant variable.)
  4. 块级作用域
  5. 对于数组和对象的元素修改,不算对常量的修改,所以不会报错

2、解构赋值

es6允许按照一定模式从数组和对象中提取值,对变量进行赋值。简便操作,提高效率。

  1. 数组的解构赋值 (命名取值只与数组顺序有关)
    let arr = ['apink', 'rose', 'jennie'],使用:let [a, r, j] = arr
  2. 对象的解构赋值 (命名要与对象中的key一致)
    let obj = {name: 'rita', age: '18', color: 'pink'}, 使用let {name,color,age} = obj

3、模板字符串

es6引入新的声明字符串的方式,字符串和变量拼接,以及直接出现换行符

4、es6简化对象写法

es6允许在大括号里直接写变量和函数,作为对象的属性和方法,这样书写更加简洁。
简略了写法:name, // name => name:name,以及change:function(){} => change(){}

5、箭头函数

let fn = function(){
}
let fn = () => {
}

特性:

  1. this是静态的。this始终指向函数声明时所在的作用域下的this的值
let getname1 = function(){
    console.log(this.name);
}
let getname2 = () => {
    console.log(this.name);
}
window.name = 'lorretta'
const person = {
    name : 'rita'
}
getname1().call(person) // rita
getname2().call(person) // lorretta
  1. 不能做为构造函数去实例化对象
let Person = (nam, age) => {
    this.nam = nam
    this.age = age
}
let me = new Person('rita', 18)
// TypeError: Person is not a constructor
  1. 不能使用arguments对象
let fn = ()=>{
    console.log(arguments)
}
fn(1,2,3)
// Uncaught ReferenceError: arguments is not defined
  1. 箭头函数的简写
    1)当形参有且只有一个的时候,可以省略小括号
    2)当代码体只有一句时,可以省略花括号,此时return必须省略
  2. 适用场景
    1)适合与this无关的回调,如定时器、数组的返回等
    2)不适合与this有关的回调,如dom里的事件回调,对象里的方法等

6、函数参数的默认值

let fn = function(a,b,c=10){
    return a + b + c
}
fn(1,2,) //13
----------
function connect({host="127.0.0.1",username,password, port}){ 
    console.log(host)
    console.log(username)
    console.log(password) 
    console.log(port) 
} 
connect({
    host: 'atguigu.com', username: 'root', password: 'root', port: 3306
})
  1. 形参初始值,具有默认的参数,一般位置靠最后(潜规则)
  2. 与解构赋值结合,可以设置默认值

7、rest

es6引入rest参数,用于获取参数的实参,用来代替arguments

function date_es5(){ 
    console.log(arguments);  
    // ['hello', 'world', 'hi', callee: ƒ, Symbol(Symbol.iterator): ƒ] 是对象
}
date_es5('hello', 'world', 'hi')
function date_es6(...args){ 
    console.log(args); // ['hello1', 'world2', 'hi3'] 是一个数组
}
date_es6('hello1', 'world2', 'hi3')  
//rest 参数必须要放到参数最后
function fn(a,b,...args){ 
    console.log(a); 
    console.log(b); 
    console.log(args);
}
fn(1,2,3,4,5,6); // 1、 2、 [3, 4, 5, 6]

8、扩展运算符

...扩展运算符能将数组转化为逗号分隔的参数序列,可以做什么:

  1. 数组的合并 let newArr = [...arr1, ...arr2]
  2. 数组的克隆(引用数据类型,是浅拷贝)
    浅拷贝:就是拷贝变量所存的值,如果是引用变量,那拷贝的就是它里面的地址
  3. 将伪数组转成真正的数组[...divArr],这样就可以使用数组的map、filter等方法

9、symbol

  • 是原始数据类型,值是唯一的,symbol就是用来创建全局唯一的值
  • 作用:为对象快速且安全的添加,独一无二的自定义的属性和方法(symbol值是唯一的,这么做应该是为了防止命名冲突)
  • 不能进行运算
  • symbol定义的对象属性不能用for...in进行循环遍历
  • 数据类型
    【usonb】:undefined、string、symbol、object、null、number、boolean
// 1、Symbol创建
let s1 = Symbol('rita')
let s2 = Symbol('rita')

// 虽然有两个rita, 但是编号是不一致的,所以不会相等
console.log(s1 == s2); // false

// 2、Symbol.for创建,这时可以得到唯一的symbol值
let s3 = Symbol.for('meiyun')
let s4 = Symbol.for('meiyun')

console.log(s3 == s4); // true

// 3、不能运算,不能进行加减乘除
false? s1 + 100 : ''
// 报错:Uncaught TypeError: Cannot convert a Symbol value to a number

// 4、作用:为对象快速且安全的添加,独一无二的自定义的属性和方法

// 5、实例:为game添加同名的up方法,且不会覆盖原有的方法
let game = {
    // 内置的重名方法
    up(){
        console.log('这是内置的up方法');
    },
    // 添加方式1
    [up=Symbol.for('up')]:function(){
        console.log('1、Symbol里的say方法, 写在对象上');
    }
}
// 添加方式2
let method = {
    up: Symbol(),
}
game[method.up] = function() {
    console.log('2、Symbol里的up方法, 写在自定义的对象method里');
}
// 进行调用
console.log(game.up()); // 这是内置的up方法
console.log(game[up]()); // 1、Symbol方法, 写在对象上
console.log(game[method.up]()); // 2、Symbol方法, 写在自定义的对象method里

10、迭代器iterator

  • 迭代器是一种接口,任何数据结构只要部署了iterator接口,就可进行遍历。
  • 有next执行方法,返回对象里包含{value, done}
    // 自定义一个迭代器方法,遍历数组对象,返回page里的值
    let obj = {
        name: 'home',
        page: [
            'search',
            'card',
            'list',
            'detail',
        ],
        // 自定义iterator接口方法 包含{value, done}
        [Symbol.iterator](){
            let arr = this.page
            let idx = 0
            return {
                next:()=>{
                    if (idx<arr.length) {
                        let result = {value:arr[idx], done: false}
                        idx++
                        return result
                    } else {
                        return {value:undefined, done: true}
                    }
                }
            }
        }
    }
    // for of 进行对象遍历
    for (const v of obj) {
        console.log(v); // search、card...
    }

for...of...遍历对象,返回键值value
for...in...遍历对象,返回键名key
forEach()
map()
filter()

11、生成器generator

  • 生成器是特殊的函数,由于异步编程,yield函数代码的分隔符,可以与for...of循环相结合
  • 生成器函数可以让几个方法顺序执行,异步编程的解决方法,next()方法
function getUser(){
    setTimeout(() => {
        console.log('用户数据')
        iterator.next()
    }, 1000);
}
function getShop(){
    setTimeout(() => {
        console.log('订单数据')
        iterator.next()
    }, 1000);
}
function getGoods(){
    setTimeout(() => {
        console.log('商品数据')
    }, 1000);
}
function * gen(){
    let user = yield getUser()
    let order = yield getShop()
    let goods = yield getGoods()
}
let iterator = gen() 
iterator.next()
// 一秒后:用户数据 =>二秒后:订单数据 =>三秒后:商品数据

12、promise

13、Set()

es6提供了新的数据结果Set,它类似于数组,但成员的值都是唯一的,可以使用【...】扩展运算符与for...of进行遍历

  1. 基本使用:
    // 1、 声明一个set: new Set()
    let s = new Set(['lv','lv','gucci', 'dior', 'chanel', 'prada'])
    // 2、检测长度size
    console.log(s.size);
    // 3、添加add
    console.log(s.add('celine'));
    // 4、删除delete
    s.delete('lv')
    // 5、检测has
    console.log(s.has('lv')); 
    // 6、清空clear
    s.clear()
    // 7、此数据结构能进行for...of遍历
    for (const v of s) {
        console.log(v);
    }
  1. 实际运用
    // 实战1:实现数组去重
    let arr1 = [1, 1, 3, 2, 3, 4, 5]
    let result = [...new Set(arr1)]
    console.log(result); //[1, 3, 2, 4, 5]
    // 实战2:求交集
    let arr2 = [1, 2, 3, 666, 999]
    let contract = [...new Set(arr2)].filter(item => new Set(arr1).has(item))
    console.log(contract); //[666, 999]
    // 实战3:求并集
    let union = [...new Set([...arr1, ...arr2])]
    console.log(union); //[1, 3, 2, 4, 5, 666, 999]
    // 实战4:求差集
    let diff = [...new Set(arr2)].filter(item => !(new Set(arr1).has(item)))
    console.log(diff); //  [666, 999]

14、Map()

map是升级版的对象,也是键值对集合。原来的key只能是字符串,现在不限制类型。可以使用【...】扩展运算符与for...of进行遍历

    // 设置一个map
    let m = new Map()
    m.set('bag', 'celine')
    m.set('buy', function () {
        console.log('我想买个celine ava');
    })
    // 读取 get
    m.get('buy')()
    // 长度 size
    console.log(m.size);
    // 删除 delete
    m.delete('bag')
    // 查询 has
    console.log(m.has('buy'));
    // 清空 clear
    m.clear()
    // 遍历 for...of
    for (const v of m) {
        console.log(v);
    }

15、class类

  • es6的创建类
    关键字是class,使用constructor对象
  • static
    实例对象与函数对象上的属性与方法是不相通的,所以叫静态成员static。static 标注的属性、方法,只属于类本身,实例对象无法调用。
  • es5 与 es6创建类
    // es5 创建类
    function Bag(brand, price) {
        this.brand = brand
        this.price = price
    }
    Bag.color = 'pink'
    Bag.prototype.slogan = function () {
        console.log('es5 包治百病~');
    }
    let celine1 = new Bag('celine', '12500')
    celine1.slogan()

    // es6 class创建类
    class Gift {
        constructor(brand, price) {
            this.brand = brand
            this.price = price
        }
        static color = 'black pink'
        // 这里不能使用 slogan:function(){}
        slogan() {
            console.log('es6 包治百病~');
        }
    }
    let celine2 = new Gift('lv', '14400')
    celine2.slogan()
    console.log(celine2);
  • 【继承】es5是构造函数与call方法结合绑定父级原型链实现继承
    // es5 构造函数实现继承
    function Animal(name, age) {
        this.name = name,
        this.age = age
    }
    Animal.prototype.say = function () {
        console.log('hello rita');
    }
    function Person(name, age, sexial, color) {
        // 继承animal
        Animal.call(this, name, age)
        this.sexial = sexial
        this.color = color

    }
    // 子级的原型绑定到父级
    Person.prototype = new Animal()
    Person.prototype.constructor = Person
    // 给子级添加原型方法
    Person.prototype.sing = function () {
        console.log('i can sing');
    }
    // 创建子级的实例
    let rita = new Person('rita', '18', '女', 'pink')
    // 调用父类的方法 console.log(rita.__proto__.say);
    // 调用自身的方法
    console.log(rita.sing);
  • 【继承】es6是通过extends关键字与super函数实现继承
    // es6 class如何实现继承
    class Animal {
        constructor(name, age) {
            this.name = name
            this.age = age
        }
        sayHi() {
            console.log('hello class');
        }
    }
    class Person extends Animal {
        constructor(name, age, sexial, color) {
            super(name, age)
            this.sexial = sexial
            this.color = color
        }
        sing() {
            console.log(this.name + ' can sing~');
        }
        // 改写父级的同名方法
        sayHi() {
            console.log(this.name + ' say hello~');
        }
    }
    // 创建实例
    const xiaomi = new Person('小米', 20, '男', 'blue')
    xiaomi.sayHi()
    console.log(xiaomi);
  • get 与 set
    class Person {
        // get 与 set方法
        get hobby() {
            console.log('hobby属性正在被读取');
            return '爱好是唱歌'
        }
        set hobby(newVal) {
            console.log('hobby属性正在被修改');
        }
    }
    // 创建实例
    const xiaomi = new Person('小米')
    xiaomi.hobby = '跑步'
    console.log(xiaomi.hobby) //爱好是唱歌

16、数值的扩展

  1. Number.EPSILON是一个非常小的数(2.220446049250313e-16),可以用来计算0.1+0.2 !== 0.3的问题
  2. Number.isFinite(10/0) 返回传入的数字是否为有限数的判断true/false
  3. Number.isNaN(NaN)判断一个数是否是NaN
  4. Number.parseInt向下取整、Number.parseFloat 转为整数
  5. Number.isInteger(1.23)判断一个数是否为整数
  6. Math.trunc()将数字的小数部分抹掉
  7. Math.sign() 判断一个数是正数1、负数-1、还是0

16、对象方法的拓展

  1. Object.is(a,b) // 判断两个值是否相等 类似于===
  2. Object.assign(obj1,obj2) // 用做配置合并,对象的克隆等, obj2会覆盖掉obj1
  3. Object.setPrototypeOf(对象,变量) 设置原型对象、Object.getPrototypeOf(变量) 读取原型对象

17、模块化

  • 优点:防止命名冲突、代码复用、高维护性
  • ES6之前的规范:CommonJS、AMD、CMD
导入import
  1. 通用导入
    import * as m1 from './module/m1.js'
  2. 解构赋值
    // name as myname 模块重名可用as起别名
    import {name as myname,fn} from './module/m1.js'
  3. 简便形式,针对默认暴露
    import m1 from './module/m1.js'
导出export
  1. 分别暴露
    export let name = 'rita' export function fn(){}
  2. 统一暴露
    export {name, fn}
  3. 默认暴露
export default {
    name:'rita',
    fn(){}
}

18、es7 数组方法的拓展

const bags = ['lv', 'gucci', 'dior', 'chanel']

// includes 类似于indexOf
console.log( bags.includes('coach'));// false
console.log( bags.includes('lv')); // true

// ** 类似于Math.pow()
console.log(2 ** 10);
console.log(Math.pow(2,10));

19、es8:async / await

参考笔记链接:抱歉了... - 简书 (jianshu.com)

20、es8:对象方法的拓展

1) Object.entries
    const obj = {
        brand: ['lv', 'gucci', 'dior', 'chanel'],
        current: 'speednano',
        cost: 16500,
    }
    // 获取键名
    console.log(Object.keys(obj)); //['brand', 'current', 'cost']
    // 获取键值
    console.log(Object.values(obj)); // [Array(4), 'speednano', 16500]
    // 获取entries
    console.log(Object.entries(obj)); // [['brand', Array(4)] ...]
    // 结合map
    const m = new Map(Object.entries(obj))  // [0: {"brand" => Array(4)} ... ]
    console.log(m.get('current')); //speednano
2) Object.getOwnPropertyDescriptor

console.log(Object.getOwnPropertyDescriptors(obj));

{
    brand = {
        configurable:true,
        enumerable:true,
        value:(4)['lv', 'gucci', 'dior', 'chanel'],
        writable:true,
        [[Prototype]]:Object,
    } ...
}

21、es9

rest拓展运算符,新增对象的展开

参数对象的展开
function fn({name,age,...params}) {}
对象的合并,浅拷贝
const mergeObj = {...one, ...two, ...three}

正则扩展
  • 命名捕获分租
  • 反向断言
  • dotAll模式

22、es10

  • 1)fromEntries
    es10 fromEntries 创建一个对象 接受一个map 或二维数组
    es08 entries 是fromEntries的逆运算,把传入的对象转成为二维数组,一个是将对象转换成二维数组,另一个是将二维数组转成对象
// 二维数组
const result1 = Object.fromEntries([
    ['name', 'rita'],
    ['age', '18']
])
console.log(result1); // {name: 'rita', age: '18'}
// Map
const m = new Map()
m.set('name', 'RITA')
const result2 = Object.fromEntries(m)
console.log(result2); // {name: 'RITA'}
  • 2)字符串的扩展方法 清除空白
    trimStart()、trimEnd()、trim()
  • 3)数组的两个方法:flat()、flatMap()
    fla将多维数组转成一维数组 [1,[2,[3]]].flat(3)
    flatMap将map结果做了一个维度降低 let arr = [1,2,3].flatMap(item=>[item*10])
  • 4)Symbol.prototype.description
    description获取symbol字符串的描述

23、es11

1)对象的私有属性

对象的私有属性,属性名前加#号,无法被外部读取和修改 (面向对象中的特性,对属性的封装)

class Person{
    name;
    #age; // #是私有属性的标识符
    constructor(name, age){ this.name = name;this.#age = age}
    intro(){console.log(this.name+'的年龄是'+ this.#age); }
}
// 实例化
const boy = new Person('eric', 22)
// 可以调用内部属性
boy.intro() // eric的年龄是22
// 直接调用会报错
console.log(boy.#age ); //Private field '#age' must be declared in an enclosing class
2)promise的allSettle()

用于批量操作异步进程的场景。

  • 都需要成功才能操作,就用all(p1,p2)
  • 需要知道每个进程返回的结果,就用allSettle(p1,p2)
3)字符串扩展的方法

String.prototype.matchAll() 返回的结果是可迭代对象,可用for循环或map进行查询和数据提取

4)可选链操作符 ?.

以前:user = config && config.admin && config.admin.user
现在:user = config?.admin?.user

5)动态import

与之相对应的是静态import,动态import可以实现按需加载

6)大整形 BigInt,可以用来做更大数值运算

let n = 520n //正常数字后加一个n
console.log(n, typeof(n)); // 520n 'bigint'
BigInt(1314) // 1314n

7)globalThis

始终指向全局对象的globalThis,如果想对全局对象进行一些读取和操作,直接使用globalThis可忽略当前执行环境

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容