如何讀取 Cookie ?
栏目: JavaScript · 发布时间: 6年前
内容简介:當我們使用VS Code 1.34.0Quokka 1.0.216
當我們使用 document.cookie() 讀取 Cookie 時,回傳為 String,我們希望提供 Key 讀取其 Value,這常見的需求該如何實現呢 ? 本文分別使用 Imperative、Functional 與 Maybe 三種方式實現。
Version
VS Code 1.34.0
Quokka 1.0.216
Ramda 0.26.1
Cookie
let readCookie = () => {
let data = document.cookie.split('; ').slice(0, -2);
console.log(getCookie('firstName')(data));
};
實務上要使用 document.cookie 去讀取 cookie,但讀出來為以下格式:
firstName=Sam; lastName=Xiao; _ga=GA1.1.320322304.1546312556; Hm_lvt_47acec2d282c3986f1b600abdc11c7ab=155525178
倒數第二個 ; 之後的資訊並不是我們要的,所以先 split() 成 array 後,用 slice() 取得不含倒數兩個 element 的新 array,最後再傳入 getCookie() ,根據 key 取得 value。
Imperative
let data = [
'firstName=Sam',
'lastName=Xiao'
];
// getCookie :: String -> [String] -> String
let getCookie = key => arr => {
for(let i = 0; i < arr.length; i++) {
let tuple = arr[i].split('=');
if (tuple[0] === key) return tuple[1];
}
return '';
};
console.log(getCookie('firstName')(data));
console.log(getCookie('lastName')(data));
console.log(getCookie('age')(data));
data 為根據 document.cookie() 所整理過的 string。
我們希望當傳入 key 時, getCookie() 回傳 value。
第 8 行
for(let i = 0; i < arr.length; i++) {
Imperative 會使用 for loop 一個一個找。
第 9 行
let tuple = s.split('=');
Array 中的 string 形式為 firstName=Sam ,可再使用 split() 拆成 array,因為很類似 tuple,變數姑且命名為 tuple 。
tuple 當然是很糟糕的命名,應該取一個有意義的變數名稱
第 10 行
if (tuple[0] === key) return tuple[1];
tuple[0] 即為 key,而 tuple[1] 為 value,因此可直接使用 if 判斷。
Imperative 會充斥著 中繼變數 ,然後就開始為 變數命名 傷腦筋,要如何使變數可讀性高又有意義,但畢竟我們在乎的是結果,這些中繼變數真的需要嗎 ? 是值得深思的問題
13 行
return '';
若傳入的 key 不存在,則回傳 empty string,避免產生 undefined 。
Functional
import { pipe, compose, split, converge, nth, objOf, map, find, propOr, prop, isNil, complement } from 'ramda';
let data = [
'firstName=Sam',
'lastName=Xiao'
];
// strToObj :: String -> Object
let strToObj = pipe(
split('='),
converge(objOf, [nth(0), nth(1)])
);
// isNotNil :: * -> Boolean
let isNotNil = complement(isNil);
// getCookie :: String -> [String] -> String
let getCookie = key => pipe(
map(strToObj),
find(compose(isNotNil, prop(key))),
propOr('', key)
);
console.log(getCookie('firstName')(data));
console.log(getCookie('lastName')(data));
console.log(getCookie('age')(data));
17 行
// getCookie :: String -> [String] -> String
let getCookie = key => pipe(
map(strToObj),
find(compose(isNotNil, prop(key))),
propOr('', key)
);
FP 不會使用 for loop 處理,可由 pipe() 清楚看出演算法流程:
- 先使用
map()將 array 內的 string 轉成 object - 再使用
find()搜尋 array 中每個 object,找到就傳回 object,否則傳回undefined - 最後使用
propOr()根據 key 取得 value
其中將 string 轉成 object,是想借助 Ramda 對 object 支援豐富 function。
可以看出 FP 解決問題方式是將問題最小化切割,然後各個擊破,與 Imperative整體思考方式不同
第 8 行
// strToObj :: String -> Object
let strToObj = pipe(
split('='),
converge(objOf, [nth(0), nth(1)])
);
split() objOf()
20 行
find(compose(isNotNil, prop(key)))
使用 find() 根據 key 找尋 value,其 predicate 為 (a -> Boolean) ,而 prop() 回傳為 a | Undefined ,因此組合 isNotNil() 使其轉成 boolean。
14 行
// isNotNil :: * -> Boolean let isNotNil = complement(isNil);
Ramda 並沒有提供 isNotNil() ,須自行組合,也可使用 compose(not, isNil) 。
21 行
propOr('', key)
由於 find() 可能回傳 undefined ,所以特別使用了 propOr() 處理。
我們可發現 FP 完全 沒有 中繼變數,所以再也不必為了變數命名而傷透腦筋
Maybe
import { pipe, compose, split, converge, nth, objOf, map, find, prop, isNil, complement } from 'ramda';
import { prop as prop_ } from 'crocks';
let data = [
'firstName=Sam',
'lastName=Xiao'
];
// strToObj :: String -> Object
let strToObj = pipe(
split('='),
converge(objOf, [nth(0), nth(1)])
);
// isNotNil :: * -> Boolean
let isNotNil = complement(isNil);
// getCookie :: String -> [String] -> Maybe String
let getCookie = key => pipe(
map(strToObj),
find(compose(isNotNil, prop(key))),
prop_(key),
);
console.log(getCookie('firstName')(data).option('N/A'));
console.log(getCookie('lastName')(data).option('N/A'));
console.log(getCookie('age')(data).option('N/A'));
Ramda 的 find() 唯一缺點就是回傳 undefined ,因此我們必須小心翼翼地使用 propOr() 處理,但這有幾個缺點:
-
undefined並非邏輯的一部分,是為了find()而處理 - 若一不小心使用了
prop(),就可能回傳undefined - 目前我們使用
propOr('', key),也就是undefined時回傳 empty string,但若使用端想自行決定undefined的 string 呢 ?
比較好的方式是回傳 Maybe ,由使用端決定 undefined 該如何處理。
21 行
find(compose(isNotNil, prop(key))), prop_(key),
由於要回傳 Maybe ,改用 Crocks 的 prop() ,而不是 Ramd 的 prop() ,因為 Crocks 很多 function 名稱與 Ramda 一樣,差異只在於回傳 Maybe ,因此 Crocks 所提供的同名 function 一律以 _ postfix 表示。
26 行
console.log(getCookie('firstName')(data).option('N/A'));
console.log(getCookie('lastName')(data).option('N/A'));
console.log(getCookie('age')(data).option('N/A'));
由於 getCookie() 回傳 Maybe ,必須透過 option() 將 Maybe 轉回 string。
若 undefined 時想顯示 N/A ,可一併傳進 option() 。
使用 Maybe 後, undefined 改由使用端處理, getCookie() 可專心處理正常邏輯,不必再為了 undefined 分心,程式碼邏輯也更清楚
以上所述就是小编给大家介绍的《如何讀取 Cookie ?》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
算法设计与分析基础
Anany levitin / 潘彦 / 清华大学出版社 / 2007-1-1 / 49.00元
作者基于丰富的教学经验,开发了一套对算法进行分类的新方法。这套方法站在通用问题求解策略的高度,能对现有的大多数算法都能进行准确分类,从而使本书的读者能够沿着一条清晰的、一致的、连贯的思路来探索算法设计与分析这一迷人领域。本书作为第2版,相对第1版增加了新的习题,还增加了“迭代改进”一章,使得原来的分类方法更加完善。 本书十分适合作为算法设计和分析的基础教材,也适合任何有兴趣探究算法奥秘的读者......一起来看看 《算法设计与分析基础》 这本书的介绍吧!