ECMAScriptの新機能3

記事の説明:この記事は、レガオのフロントエンドトレーニングキャンプのメモと経験です。何か問題がある場合は、指摘して教えていただければ幸いです。ありがとうございます。

1つ、シンボル

  • シンボルデータ型は一意の値を表します。これは、オブジェクト属性名の重複の問題を回避するために使用でき、この機能を使用してオブジェクトのプライベートメンバーをシミュレートすることもできます。

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

シンボル補足

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

詳細については、https//developer.mozilla.org/zh-CN/docs/Glossary/Symbolをご覧ください。

2、for ... ofループ

  •  forループは通常の配列をトラバースし、for ... inループはキーと値のペアをトラバースするのに適しており、foreachは配列オブジェクトをトラバースするのに適しています。新しいfor ... ofループは、すべてをトラバースするための統一された方法として使用できます。データ構造。
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终止遍历
  • 疑似配列オブジェクトは、引数オブジェクト、dom操作中の要素ノードのリストなどのfor..ofによってトラバースすることもできます。

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

for(const item of s){// 可用for of循环set
    console.log(item)//foo bar
}
  • 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
}
  • ただし、通常の物はリサイクルできません。理由は以下のとおりです。
const obj = {foo:123,bar:456}

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

イテレータ

ESにはますます構造化された配列タイプがあります。SetとMapが追加されました。さまざまなデータ構造に統一されたトラバーサルメソッドを提供するために、ES2015は、仕様標準として理解され、均一性を実現するIterableインターフェイスを提供します。 。インターフェース。Iterableインターフェースの実装は、for ... ofによってトラバースできます。[]、Set、Map for ... ofでトラバースできる3つのオブジェクトの中にこのようなSymbol(Symbol.iterator)メソッドがあり、ループでトラバースできるオブジェクトにイテレータメソッドをマウントする必要があります

 

このイテレータでは、データポインタを内部的に維持する必要があります。nextが呼び出されるたびに、ポインタは1ビット戻ります。done属性の機能は、すべての内部属性がトラバースされたことを示すことです。

for ... ofループを使用できるようにするには、イテレータインターフェイスを実装し、イテレータメソッドを内部にマウントする必要があります。このメソッドはnext()メソッドでオブジェクトを返す必要があります。このメソッドを継続的に呼び出すと、すべての内部を実現できます。データ。トラバース。

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}

3つ目は、上記の反復可能なインターフェースを実現することです。

  • オブジェクトがIterableインターフェースを実装している場合は、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('循环体') //未报错
}
  • 通常のオブジェクトは、反復インターフェイスを追加してデータを入力した後にループアウトできます。

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
}

4、イテレータデザインパターン

  • イテレータパターンの中核は、外部への統一されたトラバーサルインターフェイスを提供することです。これにより、外部は内部構造を気にする必要がなくなります。

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

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

 5、ES2015ジェネレーター 

  • ES2015ジェネレーターは、非同期プログラミングでのコールバックの過度のネストを回避し、より優れた非同期プログラミングソリューションを提供するために導入されました。

ジェネレーター機能

//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当中
  •  yieldステートメントはreturnと非常に似ていますが、メソッドの実行を終了しません。
  • このオブジェクトのnextメソッドを呼び出すと、この関数の関数本体の実行が開始されます。実行中、yieldが発生すると一時停止します。yield後の値は、nextの構造体として返されます。呼び出しを続けると、一時停止位置から継続します。実行など、最終的に完了がtrueになります。

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}

ジェネレーターアプリ

以下は2つのケースです。

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

6、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

セブン、ES2017

  • Object.valuesの詳細については、https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/valuesをご覧ください。

console.log(Object.values(obj)) //['value1','value2'] 将对象的所有值放到数组里
  • Object.entriesの詳細については、https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/entriesをご覧ください。

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' }
  • Object.getOwnPropertyDescriptorsオブジェクトのプロパティの完全な説明情報を取得します。詳細については、https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptorsを参照してください。

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
}
  • 関数パラメーターに末尾のコンマを追加します

function foo(
    bar,
    baz,
){

}

 

おすすめ

転載: blog.csdn.net/weixin_41962912/article/details/109763774