Github上有一个开源的操作Cookie的工具类,非常简洁,代码不到100行,压缩之后不到2kb,这个工具类,最大的特点就是API极其简单,语法糖设计很巧妙,让你分分钟就能记住它的使用方法,这正是封装的作用体现,让使用者不用关心内部实现,简单使用,没有记忆和学习成本。
先来看看Cookie.js的源码部分,随后,我们在用ES6的语法重构,让代码量更加精减。
API介绍
cookie(key, value, num/{})
key
cookie的键名value
cookie的值num
以天为单位的过期时间,1 表示1天后过期,0.1表示1小时后过期
如果第三个参数是一个 json对象
,那么它有以下配置
expires
: 过期时间,指定cookie的生命期。具体是值是过期日期。如果想让cookie的存在期限超过当前浏览器会话时间,就必须使用这个属性。当过了到期日期时,浏览器就可以删除cookie文件,没有任何影响。 默认浏览器关闭时过期
domain
: 域名称,指定关联的WEB服务器或域。值是域名,比如pc175.com。这是对path路径属性的一个延伸。如果我们想让 catalog.pc175.com 能够访问shoppingcart.pc175.com设置的cookies,该怎么办? 我们可以把domain属性设置成“pc175.com”,并把path属性设置成“/”。tag:不能把cookies域属性设置成与设置它的服务器的所在域不同的值。 默认为当前域名
path
: 路径,指定与cookie关联的WEB页。值可以是一个目录,或者是一个路径。如果http://www.pc175.com/devhead/index.html 建立了一个cookie,那么在http://www.pc175.com/devhead/目录里的所有页面,以及该目录下面任何子目录里的页面都可以访问这个cookie。这就是说,在http://www.pc175.com/devhead/stories/articles 里的任何页面都可以访问http://www.pc175.com/devhead/index.html建立的cookie。但是,如果http://www.pc175.com/zdnn/ 需要访问http://www.pc175.com/devhead/index.html设置的cookes,该怎么办?这时,我们要把cookies 的path属性设置成“/”。在指定路径的时候,凡是来自同一服务器,URL里有相同路径的所有WEB页面都可以共享cookies。现在看另一个例子:如果想让 http://www.pc175.com/devhead/filters/ 和http://www.pc175.com/devhead/stories/共享cookies,就要把path设成“/devhead”。 默认为当前根目录 /
secure
: 是否与服务器交互使用安全传输,指定cookie的值通过网络如何在用户和WEB服务器之间传递。这个属性的值或者是“secure”,或者为空。缺省情况下,该属性为空,也就是使用不安全的HTTP连接传递数据。如果一个 cookie 标记为secure,那么,它与WEB服务器之间就通过HTTPS或者其它安全协议传递数据。不过,设置了secure属性不代表其他人不能看到你机器本地保存的cookie。换句话说,把cookie设置为secure,只保证cookie与WEB服务器之间的数据传输过程加密,而保存在本地的cookie文件并不加密。如果想让本地cookie也加密,得自己加密数据。默认为false
两种用法
// 设置 |
源码结构
基本结构很简单,首先按传统类的定义,定义一个Cookie类的构造函数,用于返回Cookie的实例,且只返回一次,单例模式的应用。
// 定义一个Cookie的类 |
使用 cookie({test1: 121, test2: 3231, test3: 322})
向document.cookie中写入cookie信息,以这条记录来对照源码说明:
get
//调用cookie.get('test1') |
注意
这里作者使用了 window.unescape
对字符串解码可能是为了兼容低版本的IE,实际上这个方法已经从Web标准中移除了,虽然现在很多浏览器还支持,但为了尽量符合标准,应该尽量不要使用,改用decodeURIComponent去替代。MDN
set
// set('test4', 12312, 7) or set({ name1:1, name2:2 }) |
remove
处理cookie的过期,过期时间设置为-1, 让cookie失效。remove: function(names){
names = isArray(names) ? names : toArray(arguments);
for (var i = 0, l = names.length; i < l; i++) {
//调用了cookie.set,设置过期时间是-1天,让cookie失效
this.set(names[i], '', -1);
}
return names;
}
clear
//主要用来清除所有cookie,调用时使用 cookie.clear() |
all
all:function () { |
下面是重点
语法糖的设计
我们之所以可以使用两种方式去操作cookie,就是作者采用定义一个新的cookie函数,以参数的个数和类型去判断用户是想做什么样的操作,从而调用不同的方法。
然后又将Cookie类的原型上的方法赋值给cookie这个函数,以达到两种操作cookie的方法都能使用,也实现了代码的复用。
这种处理方式,在前面的 ajax
和 fetch api
的封装中也有应用。
// 提供 cookie('key', 'value', {..}) 的调用方式 |
使用ES6重构
使用ES6类的定义方法去重写这个工具类
源码90多行,重构后的代码70多行
function isPlainObject(v){ |