[TOC]html
Object.defineProperty ,顧名思義,爲對象定義屬性。在js中咱們能夠經過下面這幾種方法定義屬性.git
// (1) define someOne property name someOne.name = 'cover'; //or use (2) someOne['name'] = 'cover'; // or use (3) defineProperty Object.defineProperty(someOne, 'name', { value : 'cover' })
從上面看,貌似使用Object.defineProperty很麻煩,那爲啥存在這樣的方法呢?github
帶着疑問,咱們來看下 Object.defineProperty的定義。web
Object.defineProperty(object, propertyname, descriptor)
dom
其中descriptor的參數值得咱們關注下,該屬性可設置的值有:mvvm
var someOne = { }; Object.defineProperty(someOne, "name", { value:"coverguo" , //因爲設定了writable屬性爲false 致使這個量不能夠修改 writable: false }); console.log(someOne.name); // 輸出 coverguo someOne.name = "linkzhu"; console.log(someOne.name); // 輸出coverguo
var someOne = { }; Object.defineProperty(someOne, "name", { value:"coverguo" , configurable: false }); delete someOne.name; console.log(someOne.name);// 輸出 coverguo someOne.name = "linkzhu"; console.log(someOne.name); // 輸出coverguo
注意 在調用Object.defineProperty()方法時,若是不指定, configurable, enumerable, writable特性的默認值都是false,這跟以前所 說的對於像前面例子中直接在對象上定義的屬性,這個特性默認值爲爲 true。
並不衝突,以下代碼所示:優化
//調用Object.defineProperty()方法時,若是不指定 var someOne = { }; someOne.name = 'coverguo'; console.log(Object.getOwnPropertyDescriptor(someOne, 'name')); //輸出 Object {value: "coverguo", writable: true, enumerable: true, configurable: true} //直接在對象上定義的屬性,這個特性默認值爲爲 true var otherOne = {}; Object.defineProperty(otherOne, "name", { value:"coverguo" }); console.log(Object.getOwnPropertyDescriptor(otherOne, 'name')); //輸出 Object {value: "coverguo", writable: false, enumerable: false, configurable: false}
從上面,能夠得知,咱們能夠經過使用Object.defineProperty,來定義和控制一些特殊的屬性,如屬性是否可讀,屬性是否可枚舉,甚至修改屬性的修改器(setter)和獲取器(getter).動畫
//加入有一個目標節點, 咱們想設置其位移時是這樣的 var targetDom = document.getElementById('target'); var transformText = 'translateX(' + 10 + 'px)'; targetDom.style.webkitTransform = transformText; targetDom.style.transform = transformText;
經過上面,能夠看到若是頁面是須要許多動畫時,咱們這樣編寫transform屬性是十分蛋疼的。(┬_┬)this
但若是經過Object.defineProperty, 咱們則能夠spa
//這裏只是簡單設置下translateX的屬性,其餘如scale等屬性可本身去嘗試 Object.defineProperty(dom, 'translateX', { set: function(value) { var transformText = 'translateX(' + value + 'px)'; dom.style.webkitTransform = transformText; dom.style.transform = transformText; } //這樣再後面調用的時候, 十分簡單 dom.translateX = 10; dom.translateX = -10; //甚至能夠拓展設置如scale, originX, translateZ,等各個屬性,達到下面的效果 dom.scale = 1.5; //放大1.5倍 dom.originX = 5; //設置中心點X }
<div> <p>你好,<span id='nickName'></span></p> <div id="introduce"></div> <input type="text" id='inputDom'/> </div>
//視圖控制器 var userInfo = {}; Object.defineProperty(userInfo, "nickName", { get: function(){ return document.getElementById('nickName').innerHTML; }, set: function(nick){ document.getElementById('nickName').innerHTML = nick; } }); Object.defineProperty(userInfo, "introduce", { get: function(){ return document.getElementById('introduce').innerHTML; }, set: function(introduce){ document.getElementById('introduce').innerHTML = introduce; } })
而後就能愉快地綁定數據交互了.
userInfo.nickName = "xxx"; userInfo.introduce = "我是xxx,..." $('#inputDom').on('keyup',funtion(){ userInfo.nickName = this.value(); });
https://juejin.im/entry/59116...
https://juejin.im/entry/59239...
https://github.com/DMQ/mvvm