亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

使用Object.defineProperty實現簡單的js雙向綁定

2019-11-20 10:15:26
字體:
來源:轉載
供稿:網友

緣起

前幾天在看一些流行的迷你mvvm框架(比如avalon.js、 vue.js 這種較輕的框架,而非Angularjs、Emberjs這種較重的框架)的實現?,F代流行的mvvm框架一般都會將數據雙向綁定(two-ways data binding)做掉,作為框架自身的一個賣點( Ember.js 貌似是不支持數據雙向綁定的。),而且每種框架雙向數據綁定的實現方式都不太一致,比如Anguarjs內部使用的是 臟檢查 ,而avalon.js內部實現方式的本質是設置 屬性訪問器 。

這里不打算具體的討論各個框架對雙向數據綁定的具體實現,僅說一下前端實現雙向數據綁定的幾種常用方法,并著重講一下avalon.js實現雙向數據綁定的技術選型。

雙向數據綁定的常規實現方式

首先我們來說一下何為前端的 雙向數據綁定 。簡單的來說,就是框架的控制器層(這里的控制器層是一個泛指,可以理解為控制view行為和聯系model層的中間件)和UI展示層(view層)建立一個雙向的數據通道。當這兩層中的任何一方發生變化時,另一層將會立即(或者看起來是 立即 )自動作出相應的變化。

一般來說要實現這種雙向數據綁定關系(控制器層與展示層的關聯過程),在前端目前會有三種方式,

1.臟檢查

2.觀察機制

3.封裝屬性訪問器

臟檢查

我們說Angularjs(這里特指AngularJS 1.x.x版本,不代表AngularJS 2.x.x版本)雙向數據綁定的技術實現是臟檢查,大致的原理就是,Angularjs內部會維護一個序列,將所有需要監控的屬性放在這個序列中,當發生某些特定事件時(注意,這里并不是定時的而是由某些特殊事件觸發的),Angularjs會調用 $digest 方法,這個方法內部做的邏輯就是遍歷所有的watcher,對被監控的屬性做對比,對比其在方法調用前后屬性值有沒有發生變化,如果發生變化,則調用對應的handler。網上有許多剖析Angularjs雙向數據綁定實現原理的文章,比如 這篇 ,再比如 這篇 ,等等。

這種方式的缺點很明顯,遍歷輪訓watcher是非常消耗性能的,特別是當單頁的監控數量達到一個數量級的時候。

觀察機制

博主之前有一篇轉載翻譯的文章, Object.observe()帶來的數據綁定變革 ,說的就是使用ECMAScript7中的 Object.observe 方法對對象(或者其屬性)進行監控觀察,一旦其發生變化時,將會執行相應的handler。

這是目前監控屬性數據變更最完美的一種方法,語言(瀏覽器)原生支持,沒有什么比這個更好了。唯一的遺憾就是目前支持廣度還不行,有待全面推廣。

封裝屬性訪問器

在php中有 魔術方法 這樣一種概念,比如php中的 __get() 和 __set() 方法。在javascript中也有類似的概念,不過不叫魔術方法,而是叫做訪問器。我們來看個示例代碼,

var data = {name: "erik",getName: function() {return this.name;},setName: function(name) {this.name = name;}};

從上面的代碼中我們可以管中窺豹,比如 data 中的 getName() 和 setName() 方法,我們可以簡單的將其看成 data.name 的訪問器(或者叫做 存取器 )。

其實,針對上述的代碼,更加嚴格一點的話,不允許直接訪問 data.name 屬性,所有對 data.name 的讀寫都必須通過 data.getName() 和 data.setName() 方法。所以,想象一下,一旦某個屬性不允許對其進行直接讀寫,而必須是通過訪問器進行讀寫時,那么我當然通過重寫屬性的訪問器方法來做一些額外的情,比如屬性值變更監控。使用屬性訪問器來做數據雙向綁定的原理就是在此。

這種方法當然也有弊端,最突出的就是每添加一個屬性監控,都必須為這個屬性添加對應訪問器方法,否則這個屬性的變更就無法捕獲。

Object.defineProperty 方法

國產mvvm框架avalon.js實現數據雙向綁定的原理就是屬性訪問器。不過它當然不會像上述示例代碼一樣原始。它使用了ECMAScript5.1(ECMA-262)中定義的標準屬性 Object.defineProperty 方法。針對國內行情,部分還不支持 Object.defineProperty 低級瀏覽器采用VBScript作了完美兼容,不像其他的mvvm框架已經逐漸放棄對低端瀏覽器的支持。

我們先來MDN上對 Object.defineProperty 方法的定義,

The Object.defineProperty() method defines a new property directly on an object, or modifies an existing property on an object, and returns the object.

意義很明確, Object.defineProperty 方法提供了一種直接的方式來定義對象屬性或者修改已有對象屬性。其方法原型如下,

Object.defineProperty(obj, prop, descriptor)

其中,

obj ,待修改的對象
prop ,帶修改的屬性名稱
descriptor ,待修改屬性的相關描述
descriptor 要求傳入一個對象,其默認值如下,

/*** @{param} descriptor*/{configurable: false,enumerable: false,writable: false,value: null,set: undefined,get: undefined}

configurable ,屬性是否可配置??膳渲玫暮x包括:是否可以刪除屬性( delete ),是否可以修改屬性的 writable 、 enumerable 、 configurable 屬性。

enumerable ,屬性是否可枚舉??擅杜e的含義包括:是否可以通過 for...in 遍歷到,是否可以通過 Object.keys() 方法獲取屬性名稱。

writable ,屬性是否可重寫。可重寫的含義包括:是否可以對屬性進行重新賦值。

value ,屬性的默認值。

set ,屬性的重寫器(暫且這么叫)。一旦屬性被重新賦值,此方法被自動調用。

get ,屬性的讀取器(暫且這么叫)。一旦屬性被訪問讀取,此方法被自動調用。

下面來一段示例代碼,

var o = {};Object.defineProperty(o, 'name', {value: 'erik'});console.log(Object.getOwnPropertyDescriptor(o, 'name')); // Object {value: "erik", writable: false, enumerable: false, configurable: false}Object.defineProperty(o, 'age', {value: 26,configurable: true,writable: true});console.log(o.age); // 26o.age = 18;console.log(o.age); // 18. 因為age屬性是可重寫的console.log(Object.keys(o)); // []. name和age屬性都不是可枚舉的Object.defineProperty(o, 'sex', {value: 'male',writable: false});o.sex = 'female'; // 這里的賦值其實是不起作用的console.log(o.sex); // 'male';delete o.sex; // false, 屬性刪除的動作也是無效的

經過上述的示例,正常情況下 Object.definePropert() 的使用都是比較簡單的。

不過還是有一點需要額外注意一下, Object.defineProperty() 方法設置屬性時,屬性不能同時聲明訪問器屬性( set 和 get )和 writable 或者 value 屬性。 意思就是,某個屬性設置了 writable 或者 value 屬性,那么這個屬性就不能聲明 get 和 set 了,反之亦然。

因為 Object.defineProperty() 在聲明一個屬性時,不允許同一個屬性出現兩種以上存取訪問控制。

示例代碼,

var o = {},myName = 'erik';Object.defineProperty(o, 'name', {value: myName,set: function(name) {myName = name;},get: function() {return myName;}});

上面的代碼看起來貌似是沒有什么問題,但是真正執行時會報錯,報錯如下,

TypeError: Invalid property. A property cannot both have accessors and be writable or have a value, #<Object>

因為這里的 name 屬性同時聲明了 value 特性和 set 及 get 特性,這兩者提供了兩種對 name 屬性的讀寫控制。這里如果不聲明 value 特性,而是聲明 writable 特性,結果也是一樣的,同樣會報錯。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲精品狠狠操| 97精品视频在线| 中文字幕亚洲综合| 日韩av123| 亚洲最大激情中文字幕| 一本一本久久a久久精品综合小说| 欧美性猛交xxxxx免费看| 国产精品91久久久| 中文字幕亚洲综合| 亚洲欧美国产精品| 亚洲嫩模很污视频| 丝袜情趣国产精品| 欧美一区二区三区艳史| 欧美电影免费观看网站| 在线免费观看羞羞视频一区二区| 国产精品视频精品视频| 国产精品入口夜色视频大尺度| 日韩成人高清在线| 精品偷拍各种wc美女嘘嘘| 欧美午夜精品久久久久久久| 国产精品久久久久久久久久免费| 国产高清视频一区三区| 26uuu久久噜噜噜噜| 欧美视频免费在线| 福利视频一区二区| 国产91精品黑色丝袜高跟鞋| 久久国产精品偷| 久久精品久久久久电影| 国产精品人成电影在线观看| 欧美黄网免费在线观看| 成年人精品视频| 国产日产久久高清欧美一区| 国产精品免费一区| 性欧美亚洲xxxx乳在线观看| 久久久久久久91| 成人午夜激情网| 日韩欧美在线字幕| 久久人人爽人人爽人人片av高清| 久久久久九九九九| 亚洲午夜小视频| 孩xxxx性bbbb欧美| 91亚洲精品视频| 久久乐国产精品| 91亚洲国产精品| 国产mv免费观看入口亚洲| 久久最新资源网| 亚洲国产99精品国自产| 国产高清在线不卡| 国产精品永久免费观看| 久久频这里精品99香蕉| 欧美黑人巨大精品一区二区| 国产欧美最新羞羞视频在线观看| 97国产suv精品一区二区62| 国产一区二区三区在线观看网站| 国产精品视频免费在线观看| 久久精品一区中文字幕| 91精品国产91久久久久福利| 日韩有码片在线观看| 欧美日韩亚洲高清| 日韩亚洲欧美中文在线| 海角国产乱辈乱精品视频| xxxx欧美18另类的高清| 97碰在线观看| 国产精品专区h在线观看| 欧美日韩激情小视频| 亚洲国产精品va在线观看黑人| 欧美日韩第一视频| 欧美另类在线观看| 欧美大成色www永久网站婷| 91天堂在线视频| 欧美激情亚洲国产| 国产精品一二区| 亚洲欧美综合区自拍另类| 色阁综合伊人av| 欧美日韩国产第一页| 91麻豆国产精品| 国产欧美韩国高清| 国产成人亚洲综合91精品| 亚洲91精品在线| 亚洲欧美国产高清va在线播| 国产婷婷97碰碰久久人人蜜臀| 日韩国产一区三区| 国产精品网站视频| 欧美日韩激情网| 97久久精品在线| 日本精品一区二区三区在线| 欧美丰满少妇xxxxx做受| 97精品在线视频| 在线丨暗呦小u女国产精品| 亚洲精品一区二区三区婷婷月| 久久精品国产免费观看| 欧美成人高清视频| 超碰精品一区二区三区乱码| 伊人伊成久久人综合网小说| 中国日韩欧美久久久久久久久| 最近2019中文免费高清视频观看www99| 亚洲高清久久久久久| 欧美性猛交丰臀xxxxx网站| 欧美性生交大片免费| 欧美大片免费观看在线观看网站推荐| 久久视频国产精品免费视频在线| 欧美性生活大片免费观看网址| 黑人巨大精品欧美一区二区| 夜夜躁日日躁狠狠久久88av| 欧美激情性做爰免费视频| 在线观看亚洲区| 色综合91久久精品中文字幕| 欧美电影在线观看网站| 91天堂在线观看| 欧美性高潮床叫视频| 国产精品久久久久久av福利| 国产精品自在线| 国产精品福利网站| 欧美性色视频在线| 亚洲最大激情中文字幕| 国产日韩精品电影| 欧美精品激情blacked18| 国产精品91在线| 国产欧美va欧美va香蕉在| 亚洲精品白浆高清久久久久久| 激情懂色av一区av二区av| 美女福利视频一区| 日韩网站免费观看| 国产精品高清在线观看| 久久久久久噜噜噜久久久精品| 日韩精品视频在线播放| 91九色视频在线| 国产精品男女猛烈高潮激情| 亚洲精品狠狠操| 91亚洲精品在线观看| 国产欧美精品一区二区三区-老狼| 成人精品aaaa网站| 欧美黑人巨大精品一区二区| 成人av在线网址| 精品综合久久久久久97| 精品女厕一区二区三区| 国产精品中文在线| 国产亚洲激情视频在线| 国产精品自拍偷拍| 国产精品久久久亚洲| 国产91成人在在线播放| 久久精品国产精品亚洲| 久久久久久久影视| 国产精品极品在线| 91网站免费观看| 亚洲国产成人爱av在线播放| 亚洲第一综合天堂另类专| 国模精品视频一区二区三区| 亚洲自拍欧美色图| 国产噜噜噜噜久久久久久久久| 午夜精品一区二区三区在线播放| 国外日韩电影在线观看| 亚洲综合最新在线| 成人国产精品色哟哟| 国产精品xxx视频| 欧美在线日韩在线| 亚洲社区在线观看| 丝袜一区二区三区| 亚洲国产精品久久久久秋霞不卡| 国产精品久久久久久久久久久久久久| 欧美国产日韩一区二区在线观看| 日韩av免费网站| 亚洲女人天堂成人av在线| 成人免费视频a|