Nuevas funciones de ECMAScript 3

Descripción del artículo: Este artículo son las notas y la experiencia del campo de entrenamiento frontal de Regao. Si hay algo mal, espero que puedas señalarlo y enseñar, ¡gracias!

Uno, símbolo

  • El tipo de datos de símbolo representa un valor único, que puede usarse para evitar el problema de la duplicación del nombre de atributo del objeto, y también puede usar esta función para simular los miembros privados del objeto.

console.log(Symbol() === Symbol()) //false
//================================================
const obj = {}
obj[Symbol()] = '123'
obj[Symbol()] = '456'
console.log(obj) //{[Symbol()]:'123',[Symbol()]:'456}//作为对象唯一属性

//============================================================
const obj = {
    [Symbol()]:123
}
console.log(obj)//{[Symbol]:'123'}
//===================================================
const name = Symbol()
const person = {
    [name]:'zce',
    say(){
        console.log(this[name])
    }
}

person[Symbol()]// 无法访问 外部因为无法创建完全相同的Symbol,所以就无法直接访问到这个成员,这样该对象便实现了私有成员
person.say() //zce 内部可以拿到Symbol属性值的成员

Suplemento de símbolo

// Symbol 补充

console.log(
    //Symbol() === Symbol() false
    // Symbol('foo') === Symbol('foo')  false
)

const s1 = Symbol.for('foo') //该方法提供了字符串和Symbol一一对应的关系, 方法里维护了字符串和Symbol之间的对应关系
const s2 = Symbol.for('foo')
console.log(s1 === s2)// true

console.log(
    Symbol.for(true) === Symbol.for('true') //true 如果传入的不是字符串,方法里会转为字符串
)
// Symbol 提供了很多内置的Symbol常量,用来作为内部方法的标识,这些标识符可以让自定义对象实现一些js当中内置的接口
console.log(Symbol.iterator) 
console.log(Symbol.hasInstance)

const obj = {
    [Symbol.toStringTag]:'XObject' 
}
console.log(obj.toString())// [object Object]  把这样的字符串叫做对象的字符串标签,若想要对象的字符串标签

const obj = {
    [Symbol()]:'symbol value',
    foo:'normal value'
}

for(var key in obj){
    console.log(key)
}
console.log(Object.keys(obj))//['foo] 获取不到Symbol这样的一个属性名
console.log(JSON.stringify(obj)) //{"foo":"normal value"}  序列化obj为json字符串,Symbol属性也会被忽略掉

console.log(Object.getOwnPropertySymbols(obj))// 这个方法类似于Object.keys方法,Object.keys方法只能够获取对象中字符串属性名,而这个方法获取到的全是Symbol属性名

Para obtener más detalles, visite: https://developer.mozilla.org/zh-CN/docs/Glossary/Symbol

Dos, para ... de bucle

  •  El bucle for atraviesa matrices ordinarias, el bucle for ... in es adecuado para atravesar pares clave-valor y foreach es adecuado para atravesar objetos de matriz. El nuevo bucle for ... of se puede utilizar como una forma unificada de atravesar todos estructuras de datos.
const arr = [100,200,300,400]

for(const item of arr){
    console.log(item) //100 200 300 400
}

for(const item of arr){// for of 可以用break关键词随时终结循环
    console.log(item)
    if(item > 100){
        break
    }
}

arr.forEach() //forEach无法终止遍历
arr.some() //返回true终止遍历
arr.every()// 返回false终止遍历
  • Los objetos de pseudo-matriz también pueden ser recorridos por for..of, como el objeto de argumentos, la lista de nodos de elementos durante la operación dom

const s = new Set(['foo','bar'])

for(const item of s){// 可用for of循环set
    console.log(item)//foo bar
}
  • Atravesar el objeto Mapa
const m = new Map()
m.set('foo','123')
m.set('bar','456')
for(const item of m){
    console.log(item)// ['foo','123]  ['bar','456'] 键和值放在数组中
}

for(const [key,value] of m){
    console.log(key,value)// foo 123  bar 456
}
  • Sin embargo, los objetos ordinarios no se pueden reciclar, la razón es la siguiente
const obj = {foo:123,bar:456}

for(const item of obj){// obj不可被迭代
    console.log(item)// obj is not iterable
}

Iterador

Hay cada vez más tipos de arreglos estructurados en ES. Ahora se agregan Set y Map. Con el fin de proporcionar un método transversal unificado para una variedad de estructuras de datos, ES2015 proporciona la interfaz Iterable, que se entiende como un estándar de especificación, y logra uniformidad .interfaz. La implementación de la interfaz Iterable se puede recorrer durante ... de. [], Set, Map Existe un método Symbol (Symbol.iterator) entre los tres objetos que se pueden atravesar con for ... of, y el método iterador se debe montar en los objetos que se pueden atravesar con bucle

 

En este iterador, un puntero de datos debe mantenerse internamente. Cada vez que se llama a next, el puntero retrocederá un bit. La función del atributo done es indicar que todos los atributos internos se han atravesado.

Para poder ser for ... de bucles, debes implementar la interfaz de iterador y un método de iterador debe montarse internamente. Este método debe devolver un objeto con el método next (). Llamar a este método continuamente puede lograr todos los valores internos datos.

const Set = new Set(['foo','bar','baz'])

const iterator = Set[Symbol.iterator]()// 获取Set里面的迭代器

console.log(iterator.next()) // {value:'foo',done:false}
console.log(iterator.next()) // {value:'bar',done:false}
console.log(iterator.next()) //{value:'baz',done:false}
console.log(iterator.next())//{value:undefined,done:true}
console.log(iterator.next())//{value:undefined,done:true}

Tres, realice la interfaz iterable mencionada anteriormente

  • Si el objeto implementa la interfaz Iterable, puede usar el bucle for ... of

const obj = {//外层为自定义对象,实现了可迭代接口,称为Iterable
    [Symbol.iterator]:function(){//内部必须有一个用于返回迭代器的iterator方法
        return{// iterator 方法返回的这个对象实现了迭代器接口,这个接口约定了必须要有一个用于迭代的next方法
            next:function (){
                return{// next方法当中返回的对象,这个对象实现的是迭代结果接口,称为IterationResult,这个对象内部必须要有value属性,表示当前被迭代的数据,它的值可以使任意类型,
//除此之外还必须要有个done的布尔值用来表示 迭代是否结束
                    value:'zce',
                    done:true
                }
            }
        }
    }
}

for(const item of obj){
    console.log('循环体') //未报错
}
  • Los objetos ordinarios se pueden realizar en bucle después de agregar una interfaz iterativa e ingresar datos.

const obj = {
    store:['foo','bar','baz'],
    [Symbol.iterator]:function(){
        let index = 0
        const self = this
        return{
            next:function (){
                const result = {
                    value:self.store[index],
                    done:index >= self.store.length
                }
                index++
                return result
            }
        }
    }
}

for(const item of obj){
    console.log('循环体',item) //循环体  foo    循环体 bar  循环体  baz
}

Cuatro, patrón de diseño de iterador

  • El núcleo del patrón iterador es proporcionar una interfaz transversal unificada hacia el exterior, de modo que el exterior no tenga que preocuparse por la estructura interna.

// 场景:你我协同开发一个任务清单应用

// 我的代码 =================================
const todos ={
    life:['吃饭','睡觉','打豆豆'],
    learn:['语文','数学','外语'],
    work:['喝茶'],

    each:function(callback){ // 对外提供了统一遍历的接口
        const all = [].concat(this.life,this.learn,this.work)
        for(const item of all){
            callback(item)
        }
    },
/*迭代器模式核心就是对外提供统一遍历接口,让外部不用再去关心内部的结构是怎样的,只不过上面的each方法只适用于当前对象结构.
ES2015中的迭代器,它是语言层面实现的迭代器模式,适用于任何数据结构,只需要通过代码实现iterator方法实现它的迭代逻辑就可以了 */
    [Symbol.iterator]:function(){
        const all = [...this.life,...this.learn,...this.work]
        let index = 0
        return{
            next:function(){
                return{
                    value:all[index],
                    done:index++ >= all.length
                }
            }
        }
    }
}

// 你的代码====================================

// for(const item of todos.life){
//     console.log(item)
// }

// for(const item of todos.learn){
//     console.log(item)
// }
// for(const item of todos.work){
//     console.log(item)
// }
//当前对象的统一对外遍历方法
todos.each(function(item){
    console.log(item)
})

console.log('---------------------')

for(const item of todos){
    console.log(item)
}

 Cinco, generador ES2015 

  • El generador ES2015 se introduce para evitar un anidamiento demasiado profundo de devoluciones de llamada en la programación asincrónica y para proporcionar mejores soluciones de programación asincrónica.

Función de generador

//Generator 函数
function * foo(){
    console.log('zce')
    return 100
}

const result = foo()
console.log(result)// Object [Generator] {} 打印了一个生成器对象
console.log(result.next()) // zce {value:100,done:true} 该返回值和迭代器的返回值一样,放到value当中
  •  La declaración de rendimiento es muy similar a return, pero no finaliza la ejecución del método.
  • Llamar al siguiente método de este objeto iniciará la ejecución del cuerpo de la función de esta función. Durante la ejecución, se pausará cuando encuentre rendimiento. El valor después de rendimiento se devolverá como la estructura de siguiente. Si continúa llamando , continuará en la posición de pausa. Ejecutar, y así sucesivamente, finalmente hecho se convierte en verdadero

function *  foo(){
    console.log('1111')
    yield 100 //yield 语句跟return非常类似,但是不会结束掉方法的执行
    console.log('2222')
    yield 200
    console.log('3333')
    yield 300
}

const generator = foo()
//调用这个对象的next方法才会让这个函数的函数体开始执行,执行过程中遇到yield就会被暂停下来,yield后面的值会作为next的结构返回,继续调用的话,就会暂停的位置继续执行,如此下去,最后done变为true
console.log(generator.next()) // 1111 {value:100,done:false}
console.log(generator.next()) // 1111 {value:100,done:false} 222 {value:200,done:false} 
console.log(generator.next()) // 1111 {value:100,done:false} 222 {value:200,done:false} 333 {value:300,done:false} 
console.log(generator.next()) // 1111 {value:100,done:false} 222 {value:200,done:false} 333 {value:300,done:false} {value:undefined,done:true}

Aplicación de generador

Los siguientes son dos casos:

/案例1:发号器

function * createIdMaker(){
    let id = 1
    while(true){
        yield id++
    }
}

const idMaker = createIdMaker()

console.log(idMaker.next().value)//1
console.log(idMaker.next().value)//2
console.log(idMaker.next().value)//3
console.log(idMaker.next().value)//4

// 案例2 使用Generator 函数实现 iterator 方法

const todos = {
    life:['吃饭','睡觉','打豆豆'],
    learn:['语文','数学','外语'],
    life:['喝茶'],
    [Symbol.iterator]:function * (){
        const all = [...this.life,...this.learn,...this.work]
        // let index = 0 //不再需要手动返回一个迭代器对象,直接在iterator方法内部遍历所有的成员,通过yield去返回每一个被遍历到的对象
        // return {
        //     next:function(){
        //         return{
        //             value:all[index],
        //             done:index ++ >= all.length
        //         }
        //     }
        // }
        for(const item of all){
            yield item
        }
    }
}

for(const item of todos){
    console.log(item)
}

Seis, ES2016

//ECMAScript 2016  相对于2015只是一个小版本,仅包含两个小功能

//Array.prototype.includes -------------------------------
const arr =['foo',1,NaN,false]

console.log(arr.indexOf('foo'))//0 找到元素对应的下标
console.log(arr.indexOf('bar'))//没有找到指定元素则返回-1 
console.log(arr.indexOf(NaN))//这种方式判断会存在一个问题,不能够查找数组当中的NaN

console.log(arr.includes('foo')) //这种能直接返回布尔值,存在或者不存在

// 指数运算符 ---------------------------------------

console.log(Math.pow(2,10)) //1024 指数运算借助于Math.pow,2是底数,10是指数

console.log(2 ** 10) //1024

Siete, ES2017

console.log(Object.values(obj)) //['value1','value2'] 将对象的所有值放到数组里
console.log(Object.entries(obj)) // [['foo','value1'],['bar','value2']]  以数组的形式返回对象当中的所有的键值对

for(const [key,value] of Object.entries(obj)){
    console.log(key,value) //foo value1 //bar value2
}

console.log(new Map(Object.entries(obj))) //用entries方法转化为Map对象   Map{ 'foo' => 'value1','bar' => 'value2' }
const p1 = {
    firstName:'Lei',
    LastName:'Wang',
    get fullName(){
        return this.firstName + '' +this.LastName
    }
}

console.log(p1.fullName)

const p2 = Object.assign({},p1)
p2.firstName = 'zce'
console.log(p2.fullName) // Lei Wang  Object.assign 复制时只是把fullName当作一个普通的属性去复制,才会出现这种情况

const descriptors = Object.getOwnPropertyDescriptors(p1)
// console.log(descriptors)
const p2 = Object.defineProperties({},descriptors)
p2.firstName = 'zce'
console.log(p2.fullName) // zce Wang
const books ={
    html:5,
    css:6,
    javascript:128
}

for(const [name,count] of Object.entries(books)){
    console.log(name,count) // name 5 //css 16 //javaScript 128
}

for(const [name,count] of Object.entries(books)){
    console.log(`${name.pad}`) // html------------|005 //css-------------|016 //javascript------|128
}
  • Agregue una coma al final en los parámetros de la función

function foo(
    bar,
    baz,
){

}

 

Supongo que te gusta

Origin blog.csdn.net/weixin_41962912/article/details/109763774
Recomendado
Clasificación