★JavaScriptのObject.defineProperty()とdefineProperties()

8976 ワード

ObjectのdefinePropertyとdefinePropertiesという二つの方法はjsにおいて重要であり、主な機能はこれらの内部属性を定義または修正するために用いられ、これに対応するgetOwn PropertyDescriptorとgetOwn PropertyDescriptorsはこの行の内部属性を取得するための記述である.
以下の文章では、まずデータ記述子とアクセス記述子の属性代表の意味を紹介し、これらの四つの方法の基本機能を簡単に紹介します.これらが直接的にスキップできることを知っているなら、最後に各内部属性が様々な場面で発生する実際の効果を例に挙げて説明します.それこそがこの文章の核心内容です.この文章の概念性についての説明はやはり「javaScript高級教程」、MDNウェブサイトなどの概念を使って、正確で分かりやすいことを保証します.
データ(データ記述子)のプロパティ
データ属性は4つの内部属性の特性を記述しています.
[[Configrable]]
この属性をdeleteで削除できますか?属性の特性を変更できますか?またはアクセス属性に変更できますか?文面量を使ってオブジェクトを定義する場合、デフォルト値はtrueです.
[[Enumerable]]
この属性が列挙可能かどうか、すなわち、for-i-nループまたはObject.keys()を通じて属性に戻るかどうかを表します.直接に字面量を使ってオブジェクトを定義すると、デフォルト値はtrueです.
[Writable]
属性の値を変更できますか?字面量でオブジェクトを定義する場合、デフォルトはtrueです.
[[Value]]
この属性に対応する値は、デフォルトはundefinedです.
アクセスディスクリプタのプロパティ
アクセス器の属性には、内部属性を記述する4つの特性があります.
[[Configrable]]
データ属性の[[Configrable]]と同様に、この属性をdeleteで削除できるかどうか、属性の特性を変更できるかどうか、または属性をアクセス器の属性に変更することができますか?
[[Enumerable]]
データ属性の[[Configrable]と同様に、この属性が列挙可能かどうか、すなわちfor-i-nループまたはObject.keys()を通じて属性に戻りますか?字面量でオブジェクトを定義すれば、デフォルト値はtrueです.
[[GET]]
属性にgetterを提供する方法(オブジェクト属性にアクセスする時に呼び出す関数、戻り値は現在の属性の値)があります.getterがない場合はundefinedとなります.この方法では、戻り値を属性値として使用します.デフォルトはundefinedです
[[SET]]
属性にsetterを提供する方法(オブジェクト属性に値を設定するときに呼び出す関数)がありますが、setterがない場合はundefinedとなります.この方法は、一意のパラメータを受け取り、そのパラメータの新しい値を属性に割り当てる.デフォルトはundefinedです
属性の作成/変更/取得方法
YI、Object.defineProperty()
機能:方法は、オブジェクトに直接新しい属性を定義するか、オブジェクトの既存の属性を変更して、このオブジェクトに戻ります.configurble、writable、enumerableが指定されていない場合、これらの属性のデフォルト値はfalseであり、value、get、setが指定されていない場合、これらの属性のデフォルト値はundefined : Object.defineProperty(obj, prop, descriptor) objである.動作が必要な対象のprop:ターゲットが定義または修正が必要な属性の名称descriptor:定義または修正される属性の記述子である.
 var obj = new Object();
 
 Object.defineProperty(obj, 'name', {
     configurable: false,
     writable: true,
     enumerable: true,
     value: '  '
 })
 
 console.log(obj.name)  //  
ER、Object.defineProperties()
機能:方法は、オブジェクトに直接1つ以上の新しい属性を定義したり、既存の属性を変更したりして、オブジェクトに戻ります. :Object.defineProperties(obj,props) obj:属性を追加または変更するオブジェクト.props:オブジェクトの1つまたは複数のキーのペアは、オブジェクトに追加または変更する属性を定義する具体的な構成を示しています.
 var obj = new Object();
 Object.defineProperties(obj, {
     name: {
         value: '  ',
         configurable: false,
         writable: true,
         enumerable: true
     },
     age: {
         value: 18,
         configurable: true
     }
 })
 
 console.log(obj.name, obj.age) //   , 18
SAN、Object.getOwn PropertyDescripter()
機能:この方法は、指定されたオブジェクト上の固有属性に対応する属性記述を返す(固有属性とは、直接にオブジェクトに属性を付与し、プロトタイプチェーンから検索する必要がない属性をいう) : Object.getOwnPropertyDescriptor(obj, prop)/obj:検索対象となるオブジェクト、prop:対象オブジェクト内の属性名
 var person = {
     name: '  ',
     age: 18
 }
 
 var desc = Object.getOwnPropertyDescriptor(person, 'name'); 
 console.log(desc)      
 // {
 //     configurable: true,
 //     enumerable: true,
 //     writable: true,
 //     value: "  "
 // }
SI、Object.getOwn PropertyDescriptors()
機能:指定されたオブジェクトのすべての属性の記述子が、自身の属性がない場合は、空のオブジェクトに戻ります. : Object.getOwnPropertyDescriptors(obj)/obj:検索が必要なオブジェクト
 var person = {
     name: '  ',
     age: 18
 }
 var desc = Object.getOwnPropertyDescriptors(person);
 console.log(desc) 
 //   age: {
 //   value: 18, writable: true, enumerable: true, configurable: true}
 //    name: {
 //   value: "  ", writable: true, enumerable: true, configurable: true}
 //    __proto__: Object
各シーンの記述子属性の拡張例を解説します.
configrable
configrable属性がfalseである場合、deleteオペレータ(厳格なモードでエラーをスロー)は使用できません.
オブジェクトにデータ記述子の属性を追加します.
 var person = {};
 
 Object.defineProperty(person, 'name', {
     configurable: false,
     value: 'John'
 }) ;
 
 delete person.name   //          
 
 console.log(person.name)  // 'John'      
 
 Object.defineProperty(person, 'name', {
     configurable: true  //  
 });
 
 Object.defineProperty(person, 'name', {
     enumerable: 2  //  
 });
 
 Object.defineProperty(person, 'name', {
     writable: true  //  
 });
 
 Object.defineProperty(person, 'name', {
     value: 2  //  
 });
注意:上記は・最初に属性記述子を定義した時、writablはデフォルトでfalseとして認められています.もしwritableがtrueと定義されているなら、[[writable]]と[[value]]の属性値を変更し、他の2つの属性値をエラーとして修正します.
 var obj = {};
 
 Object.defineProperty(obj, 'a', {
     configurable: false,
     writable: true,
     value: 1
 });
 
 Object.defineProperty(obj, 'a', {
     // configurable: true, //  
     // enumerable: true,  //  
     writable: false,
     value: 2
 });
 var d = Object.getOwnPropertyDescriptor(obj, 'a')
 console.log(d);
 // {
 //     value: 2, 
 //     writable: false, 
 // }
オブジェクトにアクセスディスクリプタの属性を追加します.
 var obj = {};
 var aValue; //        ,      a     ,       aValue is not defined
 var b;
 Object.defineProperty(obj, 'a', {
     configurable : true,
     enumerable : true,
    get: function() {
         return aValue
     },
    set: function(newValue) {
         aValue = newValue;
         b = newValue + 1
     }
 })
 console.log(b) // undefined
 console.log(obj.a)  // undefined,        ,  get  ,  undefined
 obj.a = 2;  //        ,  set  ,aValue 2
 
 console.log(obj.a) // 2       ,  get  ,  aValue 2
 console.log(b) // 3    obj.a   ,  set  ,b      2,     ,vue          setter    
注意:
  • getterとsetterは同時に使用しなくてもいいですが、厳格なモードで一つだけ使用すると、エラーが発生します.
  • データ・ディスクリプタとアクセス・ディスクリプタは混在してはいけません.そうでないとエラーが発生します.
  • は、varによって定義された任意の変数を使用して、 属性値はconfigurableであり、定義されたオブジェクトも同じである.
    Writable
    Writableがfalseである場合は、definePropertyによって修正することができますが、直接に値を変更することはできません.
     var obj = {};
    
    Object.defineProperty(obj, 'a', {
        configurable: true,
        enumerable: false,
         writable: false,
        value: 1
    });
    
    Object.defineProperty(obj, 'a', {
        configurable: false,
        enumerable: true,
        writable: false ,
        value: 2
    });
    var d = Object.getOwnPropertyDescriptor(obj, 'a')
    
    console.log(d); //     
    // {
    //     value: 2, 
    //     writable: false, 
    //     enumerable: true, 
    //     configurable: false
    // }
    
    
              
    var obj = {}
    
    Object.defineProperty(obj, 'a', {
        configurable: true,
        enumerable: false,
        writable: false,
        value: 1
    });
    obj.a=2;
    var d = Object.getOwnPropertyDescriptor(obj, 'a')
    
    console.log(d); //     
    
    // {
    //     value: 1,  //       
    //     writable: false, 
    //     enumerable: true, 
    //     configurable: false
    // }
    
    Eumerable
    直接例をあげる
     var obj = {};
    Object.defineProperties(obj, {
        a: {
            value: 1,
            enumerable: false
        }, 
        b: {
            value: 2,
            enumerable: true
        },
        c: {
            value: 3,
            enumerable: false
        }
    })
    
    obj.d = 4;
    
    //   
    
    //Object.defineProperty(obj, 'd', {
    //    configurable: true,
    //    enumerable: true,
    //    writable: true,
    //    value: 4
    //})
    
    for(var key in obj) {
        console.log(key);  
        //     b,   d, a c  enumerable false,     
    } 
    
    var arr = Object.keys(obj);
    console.log(arr);  // ['b', 'd']
    
    getとset
    簡易データ双方向バインディング
     //html
     
         

    input1=>

    input2=>

    input1 1=>
    //js var oInput1 = document.getElementById('input1'); var oInput2 = document.getElementById('input2'); var oSpan = document.getElementById('span'); var obj = {}; Object.defineProperties(obj, { val1: { configurable: true, get: function() { oInput1.value = 0; oInput2.value = 0; oSpan.innerHTML = 0; return 0 }, set: function(newValue) { oInput2.value = newValue; oSpan.innerHTML = Number(newValue) ? Number(newValue) : 0 } }, val2: { configurable: true, get: function() { oInput1.value = 0; oInput2.value = 0; oSpan.innerHTML = 0; return 0 }, set: function(newValue) { oInput1.value = newValue; oSpan.innerHTML = Number(newValue)+1; } } }) oInput1.value = obj.val1; oInput1.addEventListener('keyup', function() { obj.val1 = oInput1.value; }, false) oInput2.addEventListener('keyup', function() { obj.val2 = oInput2.value; }, false)
    原文のリンク先:https://segmentfault.com/a/1190000011294519?utm_source=tag-newest葃artic leHeader 15
    疑問があれば、私のマイクロ信号を追加してください.18231133236.交流を歓迎します詳細は、私の個人ブログを訪問してください.https://www.liugezhou.online. あなたも私の個人番号に注目できます.