ES6 ~ ES13 nuevas características (1)

1 ECMA nuevo concepto de descripción

2 Uso de let y const

3 Diferencias entre let, const y var

4 Uso del alcance a nivel de bloque

5 Explicación detallada de las cadenas de plantilla

6 Uso mejorado de las funciones de ES6

Un contexto de ejecución asocia dos entornos. Entorno léxico y entorno variable.

El entorno léxico es creado por let y const; el entorno variable es creado por var.

Uso básico de let-const, las variables no se pueden declarar repetidamente

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  
  <script>
    // ES6之前
    var message1 = "Hello World"
    message1 = "Hello Coderwhy"
    message1 = "aaaaa"
    console.log(message1)

    // ES6开始
    // 1.let
    let message2 = "你好, 世界"
    message2 = "你好, why"
    message2 = 123
    console.log(message2)

    // 2.const
    // const message3 = "nihao, shijie"
    // message3 = "nihao, why"

    // 赋值引用类型
    const info = {
      name: "why",
      age: 18
    }
    // info = {}
    info.name = "kobe"
    console.log(info)




     // 1.var变量可以重复声明
    // var message = "Hello World"
    // var message = "你好, 世界"


    // 2.let/const不允许变量的重复声明
    // var address = ""
    let address = "广州市"
    // let address = "上海市"
    const info = {}
    // const info = {}


  </script>

</body>
</html>

Promoción de alcance para let-const

 // 1.var声明的变量会进行作用域的提升
    // console.log(message)
    // var message = "Hello World"

    // 2.let/const声明的变量: 没有作用域提升
    // console.log(address)
    console.log(address)
    let address = "广州市"
    const info = {}

Zona muerta temporal de let-const

 // 1.暂时性死区
    // function foo() {
    //   console.log(bar, baz)

    //   console.log("Hello World")
    //   console.log("你好 世界")
    
    // 暂时性死区是let声明变量之前的范围。
    //   let bar = "bar"
    //   let baz = "baz"
    // }
    // foo()

    // 2.暂时性死区和定义的位置没有关系, 和代码执行的顺序有关系
    // function foo() {
    //   console.log(message)
    // }

    // let message = "Hello World"
    // foo()
    // console.log(message)

    // 3.暂时性死区形成之后, 在该区域内这个标识符不能访问
    let message = "Hello World"
    function foo() {
      // 这里因为函数体里面有message,打印的地方又在message之前,会报错。
      // 如果函数里面没有message,那就会去找函数外面的message。
      console.log(message)  

      const message = "哈哈哈哈"
    }

    foo()

1

let-const no agrega ventana

 // 1.var定义的变量是会默认添加到window上的
    // var message = "Hello World"
    // var address = "广州市"

    // console.log(window.message)
    // console.log(window.address)

    // 2.let/const定义的变量不会添加到window上的
    // let message = "Hello World"
    // let address = "广州市"
    
    // console.log(window.message)
    // console.log(window.address)

    // 3.let/var分别声明变量
    var message = "Hello World"
    let adress = "广州市"

    function foo() {
      debugger
    }
    foo()

bloquear el alcance de let-const

  // 1.在ES5以及之前, 只有全局和函数会形成自己的作用域
    // 代码块
    // function foo() {
    //   console.log("Hello World")
    // }
    // 下面这个是没有作用域的,包括if(){}也是没有自己的作用域。所以在{}外面可以拿到里面的参数值
    // {
    //   var message = "Hello World"
    // }
    // console.log(message)


    // 2.从ES6开始, 使用let/const/function/class声明的变量是有块级作用域
    
    // console.log(message)
    // foo()
    {
      var message = "Hello World"
      let age = 18
      const height = 1.88

      class Person {}

      function foo() {
        console.log("foo function")
      }
    }

    // console.log(age)
    // console.log(height)
    // const p = new Person()
    foo()

aplicación de alcance de bloque let-const

 Una vez que se ejecuta la variable let definida en el alcance a nivel de bloque, se destruirá.

 Aún se puede encontrar la altura en el alcance de nivel de bloque anterior, pero no se pueden encontrar el título y la información.

¿Por qué ${i} solo devuelve 4 en la imagen siguiente? Es porque no hay alcance aquí, ${i} no se puede encontrar en la función y se buscará en el alcance de nivel superior. El alcance de nivel superior aquí es ventana. Lo que encontré aquí es después de que finaliza el bucle for. y el valor ya es 4.

 Solución a la imagen de arriba:

1 、

2. Utilice la función de ejecución inmediata.

3. ¿Se colocará la variable let en el registro del entorno a través del entorno léxico para guardar el valor de i cada vez?

 // 1.形成的词法环境
    // var message = "Hello World"
    // var age = 18
    // function foo() {}
    // let address = "广州市"

    // {
    //   var height = 1.88

    //   let title = "教师"
    //   let info = "了解真相~"
    // }

    // 2.监听按钮的点击
    const btnEls = document.querySelectorAll("button")
    // [btn1, btn2, btn3, btn4]
    // for (var i = 0; i < btnEls.length; i++) {
    //   var btnEl = btnEls[i];
    //   // btnEl.index = i
    //   (function(m) {
    //     btnEl.onclick = function() {
    //       debugger
    //       console.log(`点击了${m}按钮`)
    //     }
    //   })(i)
    // }

    
    for (let i = 0; i < btnEls.length; i++) {
      const btnEl = btnEls[i];
      btnEl.onclick = function() {
        console.log(`点击了${i}按钮`)
      }
    }

    // console.log(i)

1

Uso detallado de cadenas de plantilla

 // 1.基本用法
    // 1.1.ES6之前
    // const info = "my name is" + name + ", age is " + age

    // 1.2.ES6之后
    const info = `my name is ${name}, age is ${age}`
    console.log(info)


    // 2.标签模板字符串的用法
    function foo(...args) {
      console.log("参数:", args)
    }

    // foo("why", 18, 1.88)
    foo`my name is ${name}, age is ${age}, height is ${1.88}`

Mejora de funciones: uso de argumentos predeterminados

  // 注意: 默认参数是不会对null进行处理的
    function foo(arg1 = "我是默认值", arg2 = "我也是默认值") {
      // 1.两种写法不严谨
      // 默认值写法一:
      // arg1 = arg1 ? arg1: "我是默认值"

      // 默认值写法二:
      // arg1 = arg1 || "我是默认值"

      // 2.严谨的写法
      // 三元运算符
      // arg1 = (arg1 === undefined || arg1 === null) ? "我是默认值": arg1
      
      // ES6之后新增语法: ??
      // arg1 = arg1 ?? "我是默认值"

      // 3.简便的写法: 默认参数
      console.log(arg1)
    }

    foo(123, 321)
    foo()
    foo(0)
    foo("")
    foo(false)
    foo(null)
    foo(undefined)

Mejora de funciones: nota de argumentos predeterminados

   // 1.注意一: 有默认参数的形参尽量写到后面
    // 2.有默认参数的形参, 是不会计算在length之内(并且后面所有的参数都不会计算在length之内)
    // 3.剩余参数也是放到后面(默认参数放到剩余参数的前面)
    function foo(age, name = "why", ...args) {
      console.log(name, age, args)
    }

    foo(18, "abc", "cba", "nba")

    console.log(foo.length)

Mejora de funciones: desestructuración de argumentos predeterminados

 // 1.解构的回顾
    // const obj = { name: "why" }
    // const { name = "kobe", age = 18 } = obj

    // 2.函数的默认值是一个对象
    // function foo(obj = { name: "why", age: 18 }) {
    //   console.log(obj.name, obj.age)
    // }

    function foo({ name, age } = { name: "why", age: 18 }) {
      console.log(name, age)
    }

    function foo({ name = "why", age = 18 } = {}) {
      console.log(name, age)
    }

    foo()

Mejora de funciones: suplemento de función de flecha

  // 1.function定义的函数是有两个原型的:
    // function foo() {}
    // console.log(foo.prototype) // new foo() -> f.__proto__ = foo.prototype
    // console.log(foo.__proto__) // -> Function.prototype

    // 2.箭头函数是没有显式原型
    // 在ES6之后, 定义一个类要使用class定义
    var bar = () => {}
    // console.log(bar.__proto__ === Function.prototype)
    // 没有显式原型
    // console.log(bar.prototype)
    // var b = new bar()

Sintaxis de despliegue: uso básico de despliegue

Preste atención a distinguir cuál es el parámetro restante y cuál es el operador de expansión.

 // 1.基本演练
    // ES6
    const names = ["abc", "cba", "nba", "mba"]
    const str = "Hello"

    // const newNames = [...names, "aaa", "bbb"]
    // console.log(newNames)

    function foo(name1, name2, ...args) {
      console.log(name1, name2, args)
    }

    foo(...names)
    foo(...str)

    // ES9(ES2018)
    const obj = {
      name: "why",
      age: 18
    }
    // 不可以这样来使用
    // foo(...obj) // 在函数的调用时, 用展开运算符, 将对应的展开数据, 进行迭代
    // 可迭代对象: 数组/string/arguments

    const info = {
      ...obj,
      height: 1.88,
      address: "广州市"
    }
    console.log(info)

Asignación de referencia - copia superficial - copia profunda

Copia superficial significa que solo se copia una nueva copia, incluidos los parámetros de la primera capa, y no se crean nuevas copias para los parámetros a partir de la segunda capa. Se puede ver en la siguiente figura.

Como sugiere el nombre, copia profunda significa que también se crea una nueva copia del objeto dentro del objeto. El contenido de los dos objetos es el mismo, pero modificar el valor de un objeto no afectará los parámetros del otro.

 

 const obj = {
      name: "why",
      age: 18,
      height: 1.88,
      friend: {
        name: "curry"
      }
    }

    // 1.引用赋值
    // const info1 = obj

    
    // 2.浅拷贝
    // const info2 = {
    //   ...obj
    // }
    // info2.name = "kobe"
    // console.log(obj.name)
    // console.log(info2.name)
    // info2.friend.name = "james"
    // console.log(obj.friend.name)


    // 3.深拷贝
    // 方式一: 第三方库
    // 方式二: 自己实现
    // function deepCopy(obj) {}
    // 方式三: 利用先有的js机制, 实现深拷贝JSON
    const info3 = JSON.parse(JSON.stringify(obj))
    console.log(info3.friend.name)
    info3.friend.name = "james"
    console.log("info3.friend.name:", info3.friend.name)
    console.log(obj.friend.name)

 

Representación de números: números base y largos

// 1.进制
    console.log(100)
    console.log(0b100)
    console.log(0o100)
    console.log(0x100)

    // 2.长数字的表示
    const money = 100_00_00_0000_00_00

Proceso de uso básico de símbolos

 // ES6之前存在的问题
    // const obj = {
    //   name: "why",
    //   fn: "aaa"
    // }

    // // 添加一个新的属性 name
    // function foo(obj) {
    //   obj.why = function() {}
    // }
    // foo(obj)
    // console.log(obj.fn)


    // ES6之后可以使用Symbol生成一个独一无二的值
    const s1 = Symbol()
    // const info = { name: "why" }
    const obj = {
      [s1]: "aaa" 
    }
    console.log(obj)

    const s2 = Symbol()
    obj[s2] = "bbb"
    console.log(obj)

    function foo(obj) {
      const sKey = Symbol()
      obj[sKey] = function() {}
      delete obj[sKey]
    }

    foo(obj)

Suplemento de conocimientos adicionales sobre símbolos

 const s1 = Symbol() // aaa
    const s2 = Symbol() // bbb

    // 1.加入对象中
    const obj = {
      name: "why",
      age: 18,
      [s1]: "aaa",
      [s2]: "bbb"
    }

    // const obj1 = {}
    // obj1[s1] = "aaa"
    // obj2[s2] = "bbb"

    // const obj2 = {}
    // Object.defineProperty(obj, s1, {
    //   value: "aaa"
    // })

    // 2.获取symbol对应的key和对应的值
    console.log(Object.keys(obj))
    console.log(Object.getOwnPropertySymbols(obj))
    const symbolKeys = Object.getOwnPropertySymbols(obj)
    for (const key of symbolKeys) {
      console.log(obj[key])
    }

    // 3.description
    // 3.1.Symbol函数直接生成的值, 都是独一无二
    const s3 = Symbol("ccc")
    console.log(s3.description)
    const s4 = Symbol(s3.description)
    console.log(s3 === s4)

    // 3.2. 如果相同的key, 通过Symbol.for可以生成相同的Symbol值
    const s5 = Symbol.for("ddd")
    const s6 = Symbol.for("ddd")
    console.log(s5 === s6)

    // 获取传入的key
    console.log(Symbol.keyFor(s5))

El uso básico de Set-Map-Set --- es la colección

set se puede utilizar para deduplicar matrices.

 // 1.创建Set
    const set = new Set()
    console.log(set)

    // 2.添加元素
    set.add(10)
    set.add(22)
    set.add(35)
    set.add(22)
    console.log(set)

    const info = {}
    const obj = {name: "obj"}
    set.add(info)
    set.add(obj)
    set.add(obj)
    console.log(set)

    // 3.应用场景: 数组的去重
    const names = ["abc", "cba", "nba", "cba", "nba"]
    // const newNames = []
    // for (const item of names) {
    //   if (!newNames.includes(item)) {
    //     newNames.push(item)
    //   }
    // }
    // console.log(newNames)
    const newNamesSet = new Set(names)
    //  转成数组形式
    const newNames = Array.from(newNamesSet)
    console.log(newNames)

    // 4.Set的其他属性和方法
    // 属性
    console.log(set.size)
    // 方法
    // 4.1. add方法
    set.add(100)
    console.log(set)
    // 4.2. delete方法
    set.delete(obj)
    console.log(set)
    // 4.3. has方法
    console.log(set.has(info))
    // 4.4. clear方法
    // set.clear()
    // console.log(set)
    // 4.5. forEach
    set.forEach(item => console.log(item))

    // 5.set支持for...of
    for (const item of set) {
      console.log(item)
    }

Uso de Set-Map-WeakSet

Dado que hay referencias a tres objetos en la matriz, la recolección de basura no borrará los tres objetos porque se les asignan valores nulos. Los problemas anteriores se pueden resolver mediante conjunto débil. Pero el conjunto débil no se puede enumerar ni atravesar. No se puede encontrar el conjunto simple.

  // 1.Weak Reference(弱引用)和Strong Reference(强引用)
    let obj1 = { name: "why" }
    let obj2 = { name: "kobe" }
    let obj3 = { name: "jame" }

    // let arr = [obj1, obj2, obj3]
    // obj1 = null
    // obj2 = null
    // obj3 = null

    // const set = new Set(arr)
    // arr = null

    // 2.WeakSet的用法
    // 2.1.和Set的区别一: 只能存放对象类型
    const weakSet = new WeakSet()
    weakSet.add(obj1)
    weakSet.add(obj2)
    weakSet.add(obj3)

    // 2.2.和Set的区别二: 对对象的引用都是弱引用


    // 3.WeakSet的应用
    const pWeakSet = new WeakSet()
    class Person {
      constructor() {
        pWeakSet.add(this)
      }

      running() {
        if (!pWeakSet.has(this)) {
          console.log("Type error: 调用的方式不对")
          return
        }
        console.log("running~")
      }
    }

    let p = new Person()
    // p = null
    p.running()
    const runFn = p.running
    runFn()
    const obj = { run: runFn }
    obj.run()

 Uso básico del mapa

  const info = { name: "why" }
    const info2 = { age: 18 }

    // 1.对象类型的局限性: 不可以使用复杂类型作为key
    // const obj = {
    //   address: "北京市",
    //   [info]: "哈哈哈",
    //   [info2]: "呵呵呵"
    // }
    // console.log(obj)

    // 2.Map映射类型
    const map = new Map()
    map.set(info, "aaaa")
    map.set(info2, "bbbb")
    console.log(map)

    // 3.Map的常见属性和方法
    // console.log(map.size)
    // 3.1. set方法, 设置内容
    map.set(info, "cccc")
    console.log(map)
    // 3.2. get方法, 获取内容
    // console.log(map.get(info))
    // 3.3. delete方法, 删除内容
    // map.delete(info)
    // console.log(map)
    // 3.4. has方法, 判断内容
    // console.log(map.has(info2))
    // 3.5. clear方法, 清空内容
    // map.clear()
    // console.log(map)
    // 3.6. forEach方法
    // map.forEach(item => console.log(item))

    // 4.for...of遍历
    for (const item of map) {
      const [key, value] = item
      console.log(key, value)
    }

Uso de mapa débil

 let obj1 = { name: "why" }
    let obj2 = { name: "kobe" }

    // 1.WeakMap的基本使用
    const weakMap = new WeakMap()
    // weakMap.set(123, "aaa")
    weakMap.set(obj1, "aaa")
    weakMap.set(obj2, "bbb")

    obj1 = null
    obj2 = null

Supongo que te gusta

Origin blog.csdn.net/weixin_56663198/article/details/131667342
Recomendado
Clasificación