天天躁日日躁狠狠躁AV麻豆-天天躁人人躁人人躁狂躁-天天澡夜夜澡人人澡-天天影视香色欲综合网-国产成人女人在线视频观看-国产成人女人视频在线观看

用JavaScript對JSON進行模式匹配 (Part 2 - 實現(xiàn))

Notify & Capture
要實現(xiàn) notify 和 capture 就太容易了,我們只需要把 capture 傳入的 handler 都保存下來,然后在 notify 里面找到匹配的 handler 就可以了。
復(fù)制代碼 代碼如下:
var filterHandlerBundles = [];
Dispatch.capture = function(pattern, handler) {
var filter = createFilter(pattern);
filterHandlerBundles.push({
"filter": filter,
"handler": handler
});
};
Dispatcher.notify = function(json) {
for (var i = 0; i < filterHandlerBundles.length; i++) {
if (filterHandlerBundles[i].filter.apply(this, arguments)) {
filterHandlerBundles[i].handler(json);
}
}
};

這段代碼的邏輯很清晰,關(guān)鍵就在于 createFilter 的部分。這個函數(shù)負責(zé)把一個描述模式的 JSON 轉(zhuǎn)換為一個判斷 JSON 是否匹配的函數(shù)。
Operators
我們設(shè)計了不少的運算法,如何實現(xiàn)他們呢?記住,我們不要 switch case 。因此,我們使用一個關(guān)聯(lián)數(shù)組來保存運算符與實現(xiàn)之間的映射關(guān)系好了  。
復(fù)制代碼 代碼如下:
var operators = {};
operators["lt"] = function(testValue, value) {
return arguments.length == 2 && value < testValue;
};
operators["lte"] = function(testValue, value) {
return arguments.length == 2 && value <= testValue;
};
operators["gt"] = function(testValue, value) {
return arguments.length == 2 && value > testValue;
};
operators["gte"] = function(testValue, value) {
return arguments.length == 2 && value >= testValue;
};

這樣我們只要把 "$" 后面的運算符抽取出來,就可以立即找到對應(yīng)的判斷函數(shù)了。上面4個是比較運算符,由于實現(xiàn)比較容易,所以放在這里做例子。
一個比較難的函數(shù)是 eq ,因為它需要根據(jù)數(shù)據(jù)類型來選擇具體的判斷方式。對于 String 、 Number 、 Boolean , eq 的含義就是 == ;對于 Array , eq 的含義就是里面的每一個元素都 eq ,而且順序一致;對于 Object , eq 的含義是每一個子條件都符合,因此我們需要將每一個子條件的運算符字符串提取出來,然后調(diào)用對應(yīng)的運算符。具體可以參考完整代碼。
其他運算符會簡單一些,在此我僅僅給出提示,大家可以根據(jù)自己的實際需求這些運算符的子集或超集:

in - 遍歷數(shù)組,看能否找到至少一個 eq 的。
all - 遍歷數(shù)組,看是否每一個都存在 eq 的。
ex - 如果有傳入值,則子元素存在。
re - 用正則表達式判斷字符串是否匹配。
ld - 直接調(diào)用函數(shù)進行判斷。
寫好了嗎?不太確信自己寫得是否正確?這是我們下一篇文章要討論的內(nèi)容,讓我們先加上一個默認運算符。
復(fù)制代碼 代碼如下:
operators[""] = function(testValue, value) {
if (testValue instanceof Array) {
return operators["in"].apply(this, arguments);
} else if (testValue instanceof RegExp) {
return operators["re"].apply(this, arguments);
} else if (testValue instanceof Function) {
return operators["ld"].apply(this, arguments);
} else {
return operators["eq"].apply(this, arguments);
}
};

為什么需要一個默認運算符?這其實只是一個快捷方式。在大多數(shù)時候,我們需要的都是 eq 運算,如果每一處都要把運算符寫上,代碼將變得很復(fù)雜,也不美觀。對比一下兩個 JSON ,你覺得哪個更自然?
復(fù)制代碼 代碼如下:
Dispatcher.capture({
"status": 200,
"command": "message"
}, function(json) { /* display message */ });
Dispatcher.capture({
"status$eq": 200,
"command$eq": "message"
}, function(json) { /* display message */ });

顯然,第一個更直觀一些。因此,我們需要一個默認運算符,當(dāng)運算符字符串就是 "" 時,就通過默認運算符選擇一個運算符。
Pattern to Filter
最后,我們需要把 operators 和 createFilter 接上。這部分工作其實也不難,只要調(diào)用默認運算符就可以了。
復(fù)制代碼 代碼如下:
var createFilter = function(condition) {
return function(json) {
if (arguments.length > 0) {
return operators[""](condition, json);
} else {
return operators[""](condition);
}
};
};

為什么需要考慮 json 參數(shù)沒有傳入的情況?下次文章再告訴你。不這樣做也可以,只是有些很細小的問題而已。
寫運算符,最需要的是嚴謹性。因為 Dispatcher 是一個封裝好的組件,運算符一點點的不嚴謹,都會把缺陷埋藏得很深,很難找出來。因此,下一篇文章我們要討論的是單元測試,通過單元測試我們可以大大提高 Dispatcher 的健壯性。

JavaScript技術(shù)用JavaScript對JSON進行模式匹配 (Part 2 - 實現(xiàn)),轉(zhuǎn)載需保留來源!

鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請第一時間聯(lián)系我們修改或刪除,多謝。

主站蜘蛛池模板: 久久精品热99看二 | 狠狠色欧美亚洲狠狠色www | 孕交videosgratis乌克兰 | 久久re6热在线视频 久久er国产免费精品 | 2022久久精品国产色蜜蜜麻豆 | 免费在线观看国产 | 暖暖免费观看日本在线视频 | 制服丝袜 快播 | 理论片87福利理论电影 | 国内精品伊人久久久久 | 国产欧美一区二区精品性色tv | 俄罗斯女肥臀大屁BBW | 青青草A在在观免费线观看 青青草AV国产精品 青青草 久久久 | 脱女学小内内摸出水网站免费 | 夜里18款禁用的免费B站动漫 | 伊人不卡久久大香线蕉综合影院 | 美女扒开腿让男人桶个爽 | 成人免费一级毛片在线播放视频 | 寻找最美乡村教师颁奖晚会 | 伦理片天堂eeuss影院2o12 | 国产欧美日韩综合精品一区二区 | 使劲别停好大好深好爽动态图 | 青柠在线电影高清免费观看 | 国产人成无码视频在线观看 | 久久久久激情免费观看 | 双性将军粗壮H灌满怀孕 | 女侠含泪巨臀迎合79 | 国产精华av午夜在线观看 | 亚洲无线观看国产 | 日韩一区二区三区四区区区 | 美女被抽插到哭内射视频免费 | 欧美xxbb| 亚洲 日本 欧美 中文字幕 | 97精品在线播放 | 伊人久久亚洲精品一区 | 国产AV国片精品无套内谢无码 | 夜色55夜色66亚洲精品网站 | 99热久久这里只精品国产WWW | caoporn 在线视频 | 男人插曲女人身体视频 | 暖暖日本大全免费观看 |