監聽 javascript 對象的變化


       

     廣播: 關注微信公眾號“jQuery每日經典”,有更多資料。微信小程序 -- 前端技術API手冊 也在公眾號首次發布。有需要的聯系公眾號中QQ。

  這一章話題的由來,還要從一些學員的作業說起。寫這篇文章主要是想讓大家能從不同的角度分析問題,學習的過程中多看,多練,多想,多查,多用心。在特別多的學習網站中大部分的學習資料基本都是循規蹈矩的,例如慕課網的 javascript 入門教程中,很多講師都講了一些實例,而這些例子中的代碼風格如出一轍,沒什么新意,而且這些教程占了很大一部分比例。在這里,給大家提供另外一種思路 ------ 監聽,具體代碼的實現大家自己實現。也歡迎大家評論區寫出不同想法。

先給出監聽的概念:監聽一個對象的某個屬性是否發生變化,在該屬性變化時立即觸發制定的回調函數。

實例:購物車,想必大家肯定都接觸過,那它的功能如何去實現呢?

以某寶購物車截圖為例:

 

一、功能概述

  1. 選中商品 -- 總數,總價發生變化

  2. 增加單類商品數量 -- 總數, 總價,單類商品總價 發生變化

  3. 刪除 單類商品 -- 總數總價發生變化

二、數據模型

    單個商品數據模型{ischeck:是否選中, single:12, count, 2, total:24}

    總商品數據模型{items:商品列表, totalCount:總數, totalPrice:總價}

三、常用邏輯

    1. 點擊復選框(選中單類商品),修改總數 和 總價

    代碼格式如下:

var  singleItem = document.getElementById("復選框");
singleItem.點擊事件 = function(){}
    if(this選中){

    總數=總數+this.count;

    總價=總價+this.total;

  } else {

  總數=總數-this.count;

  總價=總價-this.total;

  }
}

四、監聽模式

        監聽模式的另一個表達方式是觀察者模式,其實並沒有什么高級的。購物車這個功能用監聽模式可以描述為:當修改什么的時候,什么發生變化。

watch(item, 'isCheck', 
  function(newVal, oldVal, obj){
     if(newVal){
       all['totalCount'] = all['totalCount'] + obj['count'];
       all['totalPrice'] = all['totalPrice'] + obj['total'];
     } else {
       ...
     }
});
item['isCheck'] = false;

  

功能其實是一樣的,只不過是從“當修改什么的時候,去修改另外的什么”這種思想轉變為了“當修改什么的時候,什么發生變化”。

 

五、相關資料

1. Object.prototype.watch()

         網址:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/watch

例1:

 

var o {p:1};
o.watch("p",function (id,oldval,newval{
 console.log("o."+id+"由"+oldval+" 變為 "+newval);
 return newval;  
});
o.p 2;
o.p 3;

上面的代碼顯示結果如下:

o.p 由 1 變為 2 
o.p 由 2 變為 3

警告:這個方法是非標准的,僅在Gecko中實現了,並且這方法主要是為了在調試的時候使用。

 

2. github上也有一些watch.js的項目,

推薦一個:https://github.com/melanke/Watch.JS

具體使用情況和對它的評價網上有不少,大家可以看一下。

 

3. 自己實現

  上面代碼中的watch方法其實是我自己手寫的,粗陋代碼如下:

function watch(obj, prop, callback){
if(prop in obj){
var old = obj[prop];
Object.defineProperty(obj,prop, {
enumerable: true,
configurable: true,
set: function(val) {
var o=old;old=val;
callback(val,o,obj);
},
get:function(){
return old;
}
});
} else {
throw new Error("no such property: " + pro);
}
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM