defineProperty的使用

1.defineProperty的使用

  

// eg one
const object1 = {};
Object.defineProperty(object1, 'property1', {
value: 42,
// writable:false //默认
// configurable:false; //默认
// enumerable:false    //默认
});
object1.property1 = 24;
console.log(object1.property1);//42

 
// eg two
const object1 = {property1:42}; //property默认可读可写可配置可枚举
Object.defineProperty(object1,'property1',{
value: 24
});
object1.property1 = 18;
console.log(object1.property1); //18
//不是说好的,Object.defineProperty中定义的属性是默认是不可写,不可配置,不可枚举的?
const property = Object.getOwnPropertyDescriptor(object1, "property1")
console.log(property);//{value: 18, writable: true, enumerable: true, configurable: true}

 
//结论
// Object.defineProperty(obj, prop, descriptor) 
// 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。
// 定义新属性的时候: 默认设置(描述符) 是不可写,不可配置,不可枚举
// 修改现有属性: 会保留之前属性的描述符 只修改对应的描述符 

// 下面是MDN的一个例子
var o = {};
o.a = 1;
// 等同于:
Object.defineProperty(o, "a", {
value: 1,
writable: true,
configurable: true,
enumerable: true
});


// 另一方面,
Object.defineProperty(o, "a", { value : 1 });
// 等同于:
Object.defineProperty(o, "a", {
value: 1,
writable: false,
configurable: false,
enumerable: false
});        
//but 利用defineProperty()来修改属性描述符时,
//必须保证属性是可配置的,也就是configurable:true
//下面又是一个例子
var myObj = {a:2};
myObj.a = 3;
myObj.a;//3
Object.defineProperty(myObj,"a",{
  value:4,
  writable:true,
  configurable:false,//不可配置
  enumerable:true
});
myObj.a; //4
myObj.a = 5;
myObj.a;//5

Object.defineProperty(myObj,"a",{
  value:4,
  writable:true,
  configurable:true,
  enumerable:true
});//TypeError
//最后一个 defineProperty(..) 会产生一个 TypeError 错误,
//不管是不是处于严格模式,尝 试修改一个不可配置的属性描述符都会出错。
//注意:如你所见,把 configurable 修改成 false 是单向操作,无法撤销!
        

//同样的道理,enumerable也只能是单向的,修改会报错
Object.defineProperty(myObj,"a",{
  value:4,
  writable:true,
  configurable:false,//只能单向改变
  enumerable:false,//只能单向改变
});//TypeError:Cannot redefine property: a

// 要注意有一个小小的例外:即便属性是 configurable:false,
// 我们还是可以 把 writable 的状态由 true 改为 false,
// 但是无法由 false 改为 true。
Object.defineProperty(myObj,"a",{
  value:4,
  writable:false,// true可以改成false
  configurable:false,//保持不变
  enumerable:true,//保持不变
});
myObj.a = 333;
myObj.a;// 5

 

  

2.defineProperty双向绑定的实现 

<div></div>
<input type="text">

<script>
let obj = {};

function watch(obj,name,callback){
   let value = obj.name;
   Object.defineProperty(obj,name,{
        set(msg){
            value = msg;
            callback(value);
         },
        get(){
           return value;
        }
});
};

function doSomething(value){
    document.querySelector('div').innerHTML = value;
    document.querySelector('input').value = value;
}

document.querySelector('input').addEventListener('input',(e) => {
       obj['msg'] = e.target.value;
});

watch(obj,'msg',doSomething);

</script>
原文地址:https://www.cnblogs.com/pittle-z/p/13740193.html