強力なJSメソッドdefinePropertyの詳細とVUE.JS双方向バインド原理

7668 ワード

Object.definePropertyはとても難しい方法です.vue.jsが双方向バインドを実現できるのは、それが与えたものだ.definePropertyは直接翻訳すると「属性を定義する」ことになりますが、この方法は属性を定義するだけでなく、属性をブロックすることもできます.
オブジェクトは複数のキー/値ペアからなる無秩序な集合であることが分かった.オブジェクト内のプロパティは、任意のタイプの値であってもよい.コンストラクション関数と字面量の形式でオブジェクトを定義できます.
var obj={};// obj=new Object;
//     (  )
obj.userName="laotie";//  obj["userName"]="laotie"
//     (  )
obj.run=function(){};//  obj["run"]=function(){};

オブジェクトに属性を追加する方法は上記の方法のほかにObject.新しいプロパティを定義したり、元のプロパティを変更したりします.
Object.defineProperty()
構文:
  • Object.defineProperty(obj, prop, descriptor)

  • パラメータの説明:
  • obj:必須.ターゲットオブジェクト
  • prop:必須.定義または変更が必要な属性の名前
  • descriptor:必須.ターゲット属性が持つ特性の前の2つのパラメータは多く言わないで、コードを見て分かりました.私たちは主に3番目のパラメータdescriptorを見て、それが何なのか見てみましょう.

  • 1、 value
    ######valueでオブジェクトのプロパティを設定できます.対応する値は任意のタイプで、デフォルトはundefinedです.
    var obj={};
    console.log(obj.userName);// undefined
    Object.defineProperty(obj,"userName",{
        value:"laozhang"
    });
    console.log(obj.userName);// laozhang
    

    既存の値を変更できます.
    var obj={};
    obj.userName="laoli"
    console.log(obj.userName);// laoli
    Object.defineProperty(obj,"userName",{
        value:"laozhang"
    });
    console.log(obj.userName);// laozhang
    

    返される値は、入力関数のオブジェクト、すなわち最初のパラメータobjです.
    var obj={};
    var obj2=Object.defineProperty(obj,"userName",{
        value:"laozhang"
    });
    console.log(obj==obj2);// true
    

    2、writable
    属性の設定に使用する値が書き換えられるかどうか.trueは許可、falseは書き換えは許可されず、デフォルトはfalse
    falseに設定すると書き換えは許可されず、エラーは投げ出されません.
    var obj={};
    Object.defineProperty(obj,"userName",{
        value:"laozhang",
        writable:false
    });
    obj.userName="laoliu";
    console.log(obj.userName);// laozhang
    

    厳密に説明すると、エラーが発生します.
    "use strict";
    var obj={};
    Object.defineProperty(obj,"userName",{
        value:"laozhang",
        writable:false
    });
    obj.userName="laoliu";
    //  :TypeError: Cannot assign to read only property 'userName' of object
    

    デフォルトはfalseで、値は変更できません.
    var obj={};
    Object.defineProperty(obj,"userName",{
        value:"laozhang"
    });
    obj.userName="laoliu";
    console.log(obj.userName);// laozhang
    

    ######はtrueに設定されており、修正が許可されています
    var obj={};
    Object.defineProperty(obj,"userName",{
        value:"laozhang",
        writable:true
    });
    obj.userName="laoliu";
    console.log(obj.userName);// laoliu
    

    3、enumerable
    この記述は、指定された属性が列挙されることを許可するかどうかを決定する(for...inまたはObject.keys()を使用する).trueに設定すると列挙できます.falseに設定し、列挙できません.デフォルトはfalseです.
    falseに設定すると列挙は許可されません
    var obj={
        age:18
    };
    Object.defineProperty(obj,"userName",{
        value:"laozhang",
        writable:false,
        enumerable:false
    });
    for(var key in obj){
        console.log(key,obj[key])// age 18
    }
    console.log(Object.keys(obj));//[ 'age' ]
    

    デフォルト値はfalseであり、列挙は許可されていません
    var obj={
        age:18
    };
    Object.defineProperty(obj,"userName",{
        value:"laozhang",
        writable:false
    });
    for(var key in obj){
        console.log(key,obj[key])// age 18
    }
    console.log(Object.keys(obj));//[ 'age' ]
    

    trueに設定し、列挙を許可
    var obj={
        age:18
    };
    Object.defineProperty(obj,"userName",{
        value:"laozhang",
        writable:false,
        enumerable:true
    });
    for(var key in obj){
        /*  age 18 
            userName laozhang*/ 
        console.log(key,obj[key]);
    }
    console.log(Object.keys(obj));//[ 'age', 'userName' ]
    

    4、configurable
    configurableは総スイッチで、falseに設定すると、指定した属性を削除したり、設定したりすることはできません(value,writable,configurable)、trueに設定したり、削除したり、設定したりすることができます.
    falseのために削除されることは許されず、エラーは報告されません.
    var obj={};
    Object.defineProperty(obj,"userName",{
        value:"laozhang",
        configurable:false
    });
    delete obj.userName;
    console.log(obj.userName);//laozhang
    

    falseのために再設定を許可しないと、エラーが発生します.
    var obj={};
    Object.defineProperty(obj,"userName",{
        value:"laozhang",
        configurable:false
    });
    Object.defineProperty(obj,"userName",{
        value:"laoli"
    });
    //  :TypeError: Cannot redefine property: userName
    

    trueの場合、削除を許可
    var obj={};
    Object.defineProperty(obj,"userName",{
        value:"laozhang",
        configurable:true
    });
    delete obj.userName;
    console.log(obj.userName);//undefined
    

    trueの場合、再設定を許可
    var obj={};
    Object.defineProperty(obj,"userName",{
        value:"laozhang",
        configurable:true
    });
    Object.defineProperty(obj,"userName",{
        value:"laoli"
    });
    console.log(obj.userName);//laoli
    

    5、get/setアクセサの説明
    このメソッドは、オブジェクトのプロパティ値を設定または取得する必要がある場合に使用できます.
    var obj={};
    var initValue="xixi";
    Object.defineProperty(obj,"userName",{
        get(){
            //    userName     
            console.log("   get");
            return initValue;
        },
        set(newValue){
            // newValue     
            console.log("   set");
            initValue= newValue+" !"
        }
    });
    
    /*     get
        xixi */
    console.log(obj.userName);
    
    obj.userName="  ";//    set
    
    /*     get
           ! */
    console.log(obj.userName);
    

    getまたはsetはペアで表示する必要はありません.どちらかを書けばいいです.
    var obj={};
    Object.defineProperty(obj,"userName",{
        get(){
            return "lala"
        }
    });
    console.log(obj.userName);//lala
    

    getメソッドまたはsetメソッドを使用する場合、writableとvalueの2つのプロパティは使用できません.
    var obj={};
    Object.defineProperty(obj,"userName",{
        value:"xixi",
        get(){
            return "lala"
        }
    });
    console.log(obj.userName);
    //  :Invalid property descriptor. Cannot both specify accessors and a value or writable attribute
    

    次に例を示します.
    var obj={};
    var userName="";
    var userArr=[];
    Object.defineProperty(obj,"userName",{
        get(){
            return userName;
        },
        set(value){
            userArr.push(value);
            userName=value;
        }
    });
    obj.userName="  ";
    obj.userName="  ";
    obj.userName="  ";
    console.log(userArr);// [ '  ', '  ', '  ' ]
    

    上記の例では、userNameが所有していた値をアクセサによって正常に格納しました.不思議で、簡単ではありませんか?
    次に、definePropertyでVUEをシミュレートすることができます.JSの双方向バインド:
    
    
    
    var myInp=document.querySelector("#myInp"); var myDiv=document.querySelector("#myDiv"); var obj={ v:"haha" } myInp.value=obj.v; myDiv.innerHTML=obj.v; Object.defineProperty(obj,"v",{ set:function(v){ myDiv.innerHTML=myInp.value=v; } }) myInp.onkeyup=function(e){ console.log(e.target.value); obj.v=e.target.value; }

    好了,马上就结束了。可能有的小伙伴会想,既然这个Object.defineProperty如此强大,每次只能设置一个属性吗?那么这玩意儿用起来也挺费劲的!那么现在大咖上场:Object.defineProperties()。你可以通过该大咖同时设置多个对象描述。

    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
    

    ———————END—————本文が好きな友达、公衆号の張培躍に注目して、もっとすばらしい内容を視聴することを歓迎します!!!