Object.defineProperty()個人的理解

23294 ワード

Object.defineProperty()個人的理解
Object.definePropertyは、オブジェクト内の属性の特性を定義するために使用され、これらの特性はオブジェクト内部の値に属しているので、JSでは直接にアクセスできない.
ES 5には、データ属性とアクセス属性を含む2つの属性があります.
データのプロパティ
データ属性はデータ値の位置を含み、この位置で値を読み取り、書き込みができます.データ属性はその挙動を記述するための4つの特性があります.
  • [[Configrable]は、プロパティを削除することができますか?属性を変更することができますか?
  • [[Enumerable]]はループによって属性に戻ることができますか?オブジェクトに直接定義される属性は、デフォルトではtrue
  • です.
  • [[Writing]]属性の値を変更することができますか?オブジェクトに直接定義された属性のデフォルト値はtrue
  • です.
  • [Value]該当属性のデータ値.属性値を読み込むとき、この位置から読み、新しい属性を書き込むとき、新しい値をこの位置に保存します.デフォルト値はundefined
  • です.
    Object.defineProperty()を使用して属性のデフォルト特性を修正し、三つのパラメータを受け取ります.属性があるオブジェクト、属性名、および記述子オブジェクトの記述子オブジェクトの属性は上記の四つの特性でなければなりません.他の属性はありません.1つ以上の値を設定すると、対応する特性値を変更できます.
    例:
    let obj = {
         
        name: "lalala",
        age: 15,
        idol: 'CR7'
    };
    Object.defineProperty(obj , 'name' , {
         
        writable: false,    //     
        enumerable: false,   //     
        value: "Well"  
    })
    
    console.log(obj.name)    //Well
    obj.name = 'Nigo'   //        ,       
    console.log(obj.name)  //Well
    
    Object.keys(obj).forEach(key => {
         
        console.log(key);   //age , idol      name  
    })
    
    何度もobject.definePropertyを呼び出して同じ属性を修正しますが、最初の修正でconfigrableをfalseに設定したら、再度修正できなくなり、エラーが発生します.
    let obj = {
         
        name: "lalala",
        age: 15,
        idol: 'CR7'
    };
    Object.defineProperty(obj , 'name' , {
            //    configurable:false        
        writable: false,    //     
        enumerable: false,   //     
        value: "Well"  
    })
    
    console.log(obj.name)    //Well
    obj.name = 'Nigo'   //        ,       
    console.log(obj.name)  //Well
    
    Object.keys(obj).forEach(key => {
         
        console.log(key);   //age , idol      name  
    })
    
    
    
    Object.defineProperty(obj , 'name' , {
         
        writable: true,    //  true
        enumerable: false,   //     
        value: "Well"  
    })
    
    obj.name = 'Nigo'   //       
    console.log(obj.name)  //Nigo
    
    let obj = {
         
        name: "lalala",
        age: 15,
        idol: 'CR7'
    };
    Object.defineProperty(obj , 'name' , {
            //    configurable:false        
        configurable:false,   //            
        writable: false,    //     
        enumerable: false,   //     
        value: "Well"  
    })
    
    console.log(obj.name)    //Well
    obj.name = 'Nigo'   //        ,       
    console.log(obj.name)  //Well
    
    Object.keys(obj).forEach(key => {
         
        console.log(key);   //age , idol      name  
    })
    
    
    
    Object.defineProperty(obj , 'name' , {
            //      
        writable: true,    
        enumerable: false,   
        value: "Well"  
    })
    
    
    
    アクセサのプロパティ
    アクセス属性にはデータ値が含まれていません.ペアgetterとsetter関数が含まれています.
    また、属性が設定されている場合は、getとsetの方法があります.これはアクセス属性です.
    getter関数
    アクセス属性の読み込み時に呼び出す関数
    setter関数
    アクセス属性を書き込む時、setter関数を呼び出して、新しい値を入力します.setter関数はデータをどう処理するかを決定します.
    アクセス器のプロパティは直接定義できません.同様にObject.defineProperty()で定義しなければなりません.
            const obj = {
         
                name: 'Well',
                _age: 22,  //                 
            }
    
           Object.defineProperty(obj , 'age' , {
         
               configurable:true,   //    delete    ,         ,           ,  false
               enumerable: true,  //      ,  false
               get() {
         
                   console.log("  age  ");
                   return this._age;
               },
               set(newV) {
         
                   console.log("    ");
                   this._age = newV;  //    setter             
               }
           });
           obj.age = 24;  //    
           console.log(obj.age); //  age      24
           obj.age = 26;  //    
           console.log(obj.age);  //  age     26
           console.log(obj._age) //26
    
    アクセス器の属性名は、オブジェクトの元の属性名と重複してはいけません.そうでないと、デッドループによりスタックがオーバーフローします.
    監視対象におけるデータの変化:
     const obj = {
         
                a: 1,
                b: 2,
                c: 3
            }
    
            Object.keys(obj).forEach(key=>{
         
                let value = obj[key]
                Object.defineProperty(obj,key,{
         
                    get(){
         
                        console.log(`  ${
           key}        `)
                        return value
                    },
                    set(v){
         
                        console.log(`${
           key}        `);
                        value = v;
                    }
                })
            })
            console.log(obj.b);  //  b          2
            obj.c = 5;  //c          
    
    ゲッターとセッターを同時に定義しなければならないわけではない.
    setterのみを定義すると、書き込みのみとなり、読めなくなり、getterの属性がない場合は、厳密モードがエラーとなり、非厳格モードがundefinedに戻ります.
    getterだけを定義すると、読むことができます.書き込みができません.厳しいモードでエラーが発生します.厳しいモードでは無視されます.
    複数の属性を定義
    Object.defineProperties()は、2つのパラメータを受信し、いずれも2つのオブジェクトで、最初は属性を追加して修正するオブジェクトです.
    2番目のオブジェクトの属性は、最初のオブジェクトに追加または変更された属性に対応します.
    例:
    const people = {
         
        _name: 'Nigo',
        _age: 28
    };
    
    Object.defineProperties(people , {
         
        _name: {
         
            value: 'HaHa',
            //       
        },
        name: {
          //         
        	get() {
         
        		return this._name;
    		}
    	},
         age: {
         
             set(newV) {
         
                 this._age = newV
             }
         }
    })
    
    属性の特性を読み取る
    Object.getOwn PropertyDescripter()
    2つのパラメータ属性があるオブジェクトと属性を読み出す属性名を返します.
    データ属性であれば、戻る対象にはconfigrable、enumerable、writabele、valueが含まれます.
    アクセス属性であれば、戻るオブジェクトにはconfigrable、enumerable、get、setが含まれます.
    JSでは、Object.getOwn PropertyDescriptor()を任意のオブジェクトに使用できます.