属性描述符Object.defineProperty()详解

本文介绍了如何利用JavaScript中的Object.defineProperty方法实现数据的双向绑定,通过get和set访问器实现属性值的监听与更新,展示了如何使数据变化自动驱动视图更新,类似于Vue.js的核心机制。

Object.defineProperty(obj, prop, descriptor)

obj 需要定义属性的对象。

prop 需被定义或修改的属性名。

descriptor 需被定义或修改的属性的描述符。

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 });

configurable: 仅当该属性的 configurable 为 true 时,该属性才能够被改变,也能够被删除。默认为 false

enumerable: 仅当该属性的 enumerable 为 true 时,该属性才能够出现在对象的枚举属性中。默认为 false

value: 该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。默认为 undefined

writable: 仅当仅当该属性的writable为 true 时,该属性才能被赋值运算符改变。默认为 false

get: 一个给属性提供 getter 的方法,如果没有 getter 则为 undefined。该方法返回值被用作属性值。undefined

set: 一个给属性提供 setter 的方法,如果没有 setter 则为 undefined。该方法将接受唯一参数,并将该参数的新值分配给该属性。默认为undefined

特殊:1.当configurable为false时,writable只能从true改为false。

          2.在 descriptor 中不能同时设置访问器(get 和 set)和 wriable 或 value,否则会错,就是说想用 get 和 set,就不能用 writable 或 value 中的任何一个。

 

get和set是我们今天要重点讨论的两个方法,先看一下他们的简单实例:

js中神奇的Object.defineProperty方法

虽然我将a.b的值设置成了1,但是因为我在get方法中始终返回了2,所以a.b的值一直是2。

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>test</title>
</head>
<body>
<script>
  var book={
    _year: 2004,
    edition:1
  };
  Object.defineProperty(book,"year",{
    get: function(){
      return this._year;
    },
    set : function(newValue){
      if (newValue > 2004){
        this._year = newValue;
        this.edition = newValue;
      }
    }
  });
  console.log(book.year)   //2004
  book.year =2005;
  console.log(book.year)   //2005
  console.log(book);   //{_year: 2005, edition: 2005}
</script>
</body>
</html>

那么,这就好玩儿了:我们可以在页面监听某个变量,当变量发生变化的时候,我们就更新对应的视图。由数据来驱动视图的更新,是不是很熟悉?是的,vue .js的核心思想就是这个。我们写个小例子:

<!DOCTYPE html> 
<html> 
 <head> 
 <meta charset="UTF-8"> 
 <title>test</title> 
 </head> 
 <body> 
 <div id="test">这是一个测试</div> 
 <script> 
 var view = document.getElementById("test"); 
 var data = {}; 
 var i=0; 
 Object.defineProperty(data, "b", { 
 set: function(newValue) { 
 //当data.b的值改变的时候更新#test的视图 
 view.textContent=newValue; 
 }, 
 get: function() { 
 } 
 }); 
 setInterval(function(){ 
 i++; 
 data["b"] = "data.b的值更新了,我要更新视图"+i; 
 },1000); 
 </script> 
 </body> 
</html>

视图的变化过程:

js中神奇的Object.defineProperty方法

最开始的视图

js中神奇的Object.defineProperty方法

1秒后的视图

js中神奇的Object.defineProperty方法

转载于:https://my.oschina.net/u/3219445/blog/1554934

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值