燃芯的技术文档

vuePress-theme-reco RanxinStart    2020 - 2022
燃芯的技术文档

Choose mode

  • dark
  • auto
  • light
Category
  • 语言
  • 服务端
  • 命令行
  • 前端
  • 工程化
  • 文章
Tag
author-avatar

RanxinStart

28

Article

18

Tag

Category
  • 语言
  • 服务端
  • 命令行
  • 前端
  • 工程化
  • 文章
Tag

ECMAScript6~11

vuePress-theme-reco RanxinStart    2020 - 2022

ECMAScript6~11

RanxinStart 2021-08-14 JavaScript

# 初步认识ECMA

# 1. 什么是ECMA

​ ECMA全称是European Computer Manufacturers Association(欧洲计算机制造商协会)

​ ECMAScript是由网景开发的一种脚本语言的标准化规范;最初命名为Mocha,后来改名为LiveScript,最后重命名为JavaScript

​ ECMAScript 是由 ECMA-262标准化的程序设计语言

ECMA-262是 ECMA制定的许多标准之一

# 2. 为什么与ES6为主

​ ES6是 ECMAScript 2015的标准,在ES6版本中变更内容最多,具有里程碑的意义。ES6中加入了许多新的语法特性,编程实现更简单高效。ES6是前端发展的趋势,就业必备的技能。

# 3.ES6~ES11的兼容问题

​ 在这里可能会有一个疑问,新出的标准在旧的浏览器上面可能会出现兼容问题。例如说现在使用最新的ES11(ECMAScript2020)标准,可能会在2020年以前的浏览器无法使用,这时就要使用Babel了。

​ Babel是一个 JavaScript 编译器,能讲ES6以上的代码编译成ES5的代码后,在浏览器中运行。这样即使你使用的是ES11的代码,最终经过编译后也会变成ES5的代码在旧的浏览器中执行。

并且不会报错

# ES6~11

# 1. 声明变量

​ 新语法中使用let和const声明变量,let&const变量不会造成全局污染,也不会有变量提升。

// es5
var A = 5;
// es6
let B = 5;
// const和let的区别在于const是常量,无法修改const声明的常量
// 如果const中声明的是一个高级数据,它的值是一个地址。这时可以修改高级数据的内的值
const C = 5;

# 2. 解构赋值

// 定义ABC三个常量ABC 得到1 2 3
const [A, B, C] = [1, 2, 3]
// 定义DE和Name三个常量 得到1 2 3
const { D, E, F:Name } = { D:1,E:2,F:3 }

# 3. 模板字符串

const str1 = "我是字符串变量"
const str2 = `我是模板字符串:${str1}`
console.log(str2) // 我是模板字符串:我是字符串变量
// 可以在字符串中直接使用换行符
const str3 = `
	<div>
		这里不会报错哦
	</div>
`

# 4. 对象简化

const num = 1;
// 这里要实现得到一个对象 含有num和num的值 以及一个getName方法
// es5
var obj1 = {
    num:num,
    getName:function(){
        return 'obj1'
    }
}
// es6
const obj2 = {
    num,
    getName(){
    	return 'obj2'   
    },
    getAge:()=> 'obj2'
}

# 5. 箭头函数

​ 箭头函数不只是一个简化function的语法,箭头函数还是一个没有this的函数,在箭头函数中使用this实际上使用的是外部的this,它也有函数作用域

​ 箭头函数没有this,所以使用call或是apply修改this是无效的。

const fun1 = (a) => { return a}
const fun2 = (a) => a
const fun3 = a => a
const fun4 = a => ({a}) //返回了一个对象 {a:传入的值}

​ 箭头函数不能作为构造函数使用

// 普通函数
function fun5(name) {
    this.name = name
}
const obj5 = new fun5('fun5') // 得到一个实例化对象
// 箭头函数
let fun6 = (name) => {
    this.name = name
}
const obj6 = new fun6('fun6') // TypeError 报错 fun6 is not a constructor

​ 箭头函数没有arguments变量

(() => {
  console.log(arguments)
})(1,2,3)  // TypeError arguments is not defined

# 6. 函数默认值

​ 基础函数默认值

const defaultFun = (a = 5,b = 10) => {
    return a + b
}
// 因为a传了1所以没有使用默认值 b没有传是undefined所以得到默认值10
defaultFun(1) // 11  a:1  b:10  
// 如果穿的值是一个undefined 那么也会视为值未定义 而使用默认值
defaultFun(1,undefined) // 11  a:1  b:10  

​ 解构时默认值

const defaultFun1 = ({ a=5, b=10 }) =>{
    return a + b
}
// 和上面相同
defaultFun1({a:1}) // 11  a:1  b:10 

​ 解构别名 + 默认值

const defaultFun2 = ({ a:after = 5 }) =>{
    console.log(a) // a is not defined
    console.log(after) // 5
}
defaultFun2()

# 7. 扩展运算符

​ 能将数组或是对象进行拆包扩展

# 1.数据合并

const arr1 = [1,2,3]
const arr2 = [4,5,6]
const arr3 = [...arr1,...arr2] // [1,2,3,4,5,6]
const obj1 = { a:1 }
const obj2 = { b:2 }
const obj3 = { ...obj1, ...obj2 } // { a:1, b:2 }

# 2.数据克隆(浅拷贝)

const arr1 = [1,2,3]
const arr2 = [...arr1]
// 对象也一样 看数据合并就知道怎么操作了...

# 3.伪数组转真数组

​ 将有迭代器的数组对象转为数组

function fun1(){
    const argArr = [...arguments]
    // 得到一个真数组
}

# 8. Rest参数(剩余参数)

​ rest参数只能在最后使用

((a,...args) = >{
    console.log(a) // 输出第一个值 1
    console.log(args) // 输出剩余值 [2,3,4] 数组
})(1,2,3,4)

# 9. Symbol

  • ES6新的数据类型,表示一个独一无二的值
  • Symbol的值是唯一的,可以用来解决命名冲突问题
  • Symbol的值不能进行数据运算
  • Symbol定义的对象属性不能使用for...in遍历,但可以使用Reflect.ownKeys来获取对象所有键值

# 1.创建一个Symbol值

// 创建一个Symbol 可传入一个描述字符串
let s = Symbol()
let s1 = Symbol("s1")
// 唯一性
let s2 = Symbol("s1")
console.log(s1 === s2) // false
// 创建相同的全局共享Symbol
let s3 = Symbol.for("s3")
let s4 = Symbol.for("s3")
console.log(s3 === s4) // true

# 2.Symbol在对象中的应用

​ 唯一调用,只能用原来的Symbol调用

const key = Symbol('这是一把钥匙')
const obj1 = {
    [key]:'宝箱'
}
console.log(obj1) // { Symbol('这是一把钥匙'):'宝箱' } 但无法调用
console.log(obj1['Symbol(这是一把钥匙)']) // undefined 与对象内属性相同名字但无法调用
console.log(obj1[Symbol('这是一把钥匙')]) // undefined 重新传入一个新的Symbol无法调用
console.log(obj1[key]) // 用原来定义的key才可以调用

# 3.Symbol修改原型行为

​ 除了自己创建的symbol,JavaScript还内建了一些在ECMAScript 5 之前没有暴露给开发者的symbol,它们代表了内部语言行为。它们现在可以使用Symbol来访问并进行修改。

# 1.Symbol.iterator

​ 一些内置类型拥有默认的迭代器行为,其他类型(如 Object (opens new window))则没有。

下表中的内置类型拥有默认的@@iterator方法:

  • Array.prototype[@@iterator]() (opens new window)
  • TypedArray.prototype[@@iterator]() (opens new window)
  • String.prototype[@@iterator]() (opens new window)
  • Map.prototype[@@iterator]() (opens new window)
  • Set.prototype[@@iterator]() (opens new window)
# 修改原迭代器

​ 修改数组中的迭代器

const arr1 = [1,2,3]
arr1[Symbol.iterator] = function* (){
    yield 5
    yield 6
    yield 7
    yield 8
}
for(const it of arr1){
    console.log(it) // 依次打印 5 6 7 8
}
// 数组内的值不会改变
console.log(arr1) // [1,2,3]

​ 将arr1数组for...of得到的值翻倍

const arr1 = [1,2,3]
arr1[Symbol.iterator] = function* (){
    //  这里的this指向arr1自己
    for(let i = 0;i < this.length;i++){
        yield this[i] * 2
    }
}
for(const it of arr1){
    console.log(it) // 依次打印 2 4 6
}
console.log(arr1) // [1,2,3]

​ 将所有数组for...of得到的值都翻倍

Array.prototype[Symbol.iterator] = function* () {
    for (let i = 0; i < this.length; i++) {
        yield this[i] * 2
    }
}
const arr1 = [1, 2, 3]
const arr2 = [2, 3, 4]
for (const it of arr1) {
    console.log(it) // 依次打印 2 4 6
}
for (const it of arr2) {
    console.log(it) // 依次打印 4 6 8
}
# 对象添加迭代器

​ 原本在对象中使用for...of是会报错的

const obj = { a:1 }
for(const it of obj){}  // obj is not iterable

​ 为对象添加迭代器后 即可for...of对象

const obj = {
    *[Symbol.iterator](){
        yield 0
        yield 1
    },
}
for (const iterator of obj) {
    console.log(iterator) // 依次打印 0 1
}

​ 为对象原型添加Symbol.iterator迭代器实现key,value的for...of

Object.prototype[Symbol.iterator] = function* () {
    for (const key in this) {
        yield [key, this[key]]
    }
}
const obj = { a: 0, b: 1 }
for (const [key, value] of obj) {
    console.log(key, value) //依次输出 a0 b1
}