Nouvelles fonctionnalités d'ECMAScript 3

Description de l'article: Cet article est les notes et l'expérience du camp d'entraînement frontal de Regao. S'il y a quelque chose qui ne va pas, j'espère que vous pourrez le signaler et enseigner, merci!

Un, symbole

  • Le type de données Symbol représente une valeur unique, qui peut être utilisée pour éviter le problème de la duplication du nom d'attribut d'objet, et peut également utiliser cette fonctionnalité pour simuler les membres privés de l'objet

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属性值的成员

Supplément de symbole

// 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属性名

Pour plus de détails, veuillez visiter: https://developer.mozilla.org/zh-CN/docs/Glossary/Symbol

Deux, pour ... de boucle

  •  La boucle for traverse des tableaux ordinaires, la boucle for ... in convient pour parcourir des paires clé-valeur et foreach convient pour parcourir des objets de tableau. La nouvelle boucle for ... of peut être utilisée comme un moyen unifié de tout parcourir. structures de données.
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终止遍历
  • Les objets pseudo-tableau peuvent également être parcourus par for..of, comme un objet arguments, une liste de nœuds d'élément pendant l'opération dom

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

for(const item of s){// 可用for of循环set
    console.log(item)//foo bar
}
  • Traverser l'objet Map
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
}
  • Cependant, les objets ordinaires ne peuvent pas être recyclés, la raison est la suivante
const obj = {foo:123,bar:456}

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

Itérateur

Il existe de plus en plus de types de tableaux structurés dans ES. Set et Map sont maintenant ajoutés. Afin de fournir une méthode de traversée unifiée pour une variété de structures de données, ES2015 fournit l'interface Iterable, qui est comprise comme une norme de spécification, et atteint l'uniformité. interface. L'implémentation de l'interface Iterable peut être parcourue par for ... of. [], Set, Map Il existe une telle méthode Symbol (Symbol.iterator) parmi les trois objets qui peuvent être parcourus par for ... of, et la méthode iterator doit être montée sur les objets qui peuvent être parcourus par boucle

 

Dans cet itérateur, un pointeur de données doit être conservé en interne. À chaque appel suivant, le pointeur recule d'un bit. La fonction de l'attribut done est d'indiquer que tous les attributs internes ont été parcourus.

Pour pouvoir être pour ... des boucles, vous devez implémenter l'interface de l'itérateur, et une méthode d'itérateur doit être montée en interne. Cette méthode doit renvoyer un objet avec la méthode next (). L'appel continu de cette méthode peut atteindre tous les données.

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}

Troisièmement, réalisez l'interface itérative mentionnée ci-dessus

  • Si l'objet implémente l'interface Iterable, vous pouvez utiliser la boucle 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('循环体') //未报错
}
  • Les objets ordinaires peuvent être mis en boucle après l'ajout d'une interface itérative et l'introduction de données.

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
}

Quatre, modèle de conception d'itérateur

  • Le noyau du modèle d'itérateur est de fournir une interface de traversée unifiée vers l'extérieur, de sorte que l'extérieur n'a pas besoin de se soucier de la structure interne.

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

// 我的代码 =================================
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)
}

 Cinq, générateur ES2015 

  • Le générateur ES2015 est introduit pour éviter une imbrication trop profonde des rappels dans la programmation asynchrone et pour fournir de meilleures solutions de programmation asynchrone

Fonction générateur

//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当中
  •  L'instruction yield est très similaire à return, mais ne met pas fin à l'exécution de la méthode
  • L'appel de la méthode suivante de cet objet lancera l'exécution du corps de la fonction de cette fonction. Pendant l'exécution, il sera mis en pause lorsqu'il rencontrera yield. La valeur après yield sera renvoyée en tant que structure de next. Si vous continuez à appeler , il continuera à la position de pause. Exécuter, et ainsi de suite, enfin terminé devient vrai

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}

Application générateur

Voici deux cas:

/案例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)
}

Six, 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

Sept, 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
}
  • Ajouter une virgule de fin dans les paramètres de la fonction

function foo(
    bar,
    baz,
){

}

 

Je suppose que tu aimes

Origine blog.csdn.net/weixin_41962912/article/details/109763774
conseillé
Classement