#data.js data.js在浏览器环境中默认占用全局变量Data,在模块化编程环境中,引用模块返回Data,返回的Data是一个数据中心+工厂函数,可直接将其作为一个数据中心使用,也可通过该函数创建新的数据中心。 //一下两种方式均可获取数据中心的实例 var D = Data(); var D = new Data(); //有一个数据中心,与上面的D无关系 var F = new Data(); //在实例化的数据中心上操作 F.set(***); //在默认的数据中心上操作 Data.set(***); ##noConflict 此函数会在以原始方式在浏览器中引入是存在,用来释放Data占用的全局变量Data。同时返回Data。 - return {Function} Data demo var D = Data.noConflict();//释放Data,并赋值给D ##version 获取data.js的版本号,字符串,仅在Data上存在。 console.log(Data.version);//0.1.0 console.log(Data().version);//undefined ##has 判断Data中是否存在,指定的数据。 - key {String} 要判断的键,点号是分隔符,用来分隔对象层次 - return {Bollean} 是否包含指定键值 demo Data.has(key);//返回true或false ##get* 从Data中获取指定的键值。 - key {String} 要获取的键 - return {val} 返回与键值对应的数据,若键值的上游不存在,会返回undefined或null demo Data.get('a');//undefined Data.get('a.b.c')//undefined **注:**此处获取的是Data中数据的深拷贝,即get接口返回的数据是Data中对应数据的一份深拷贝。之所以牺牲性能,这样设计是因为深拷贝能避免很多难以预知的bug。 下面是深拷贝,浅拷贝和引用的区别: //深拷贝 var a = Data.get('a');//若a为{b:{c:1}} a.b.c= 2;//此处更改不会影像Data中的数据 Data.get('a.b.c')//此处输出1 //浅拷贝 var a = Data.get('a');//若a为{b:{c:1}} a.b.c= 2; Data.get('a.b.c')//此处输出2 //仅返回引用 var a = Data.get('a');//若a为{b:{c:1}} a.b = 1; Data.get('a.b')//此处输出1 ##set* 向Data中放入数据。若已存在,则是扩展当前数据,不会重新赋值(对于数组或对象,对于其他类型值会覆盖)。 - key {String} 放入Data中数据的键值 - val {val} [可选] 放入Data中的数据 - return {Bollean} 是否添加成功 传入key + val 和 传入 {key: val}的方式等价,可以选择自己喜欢的方式,键值的方式更清晰,作者推荐前一种,记住只使用同一种方式会让事情变得简单。 demo //传入值类型 D.set('a', 1); D.get('a');//1 //传入引用类型 D.set('a', {b: 1}); D.get('a.b');//1 D.set('a.b.c', 1); D.set('a', {b: {c: 1}}});//这两种功能一样 ###key key值是Data的基石,key是一个字符串,Data的key支持任何utf-8编码的字符,js支持的就可以 - 字母 abc - 数字 123 - 特殊字符 _-+$;'"... - 甚至是汉字 颜海镜 Data都可以完美支持,同时key还有类似对象属性的特性,a.b.c是获取a下的b下的c,其中.号是分隔符,可以想像成js中的对象(其实Data内部确实是按对象处理)。 D.set('a', {}); D.set('a.b', 1); D.set('a.c', [1]); D.set('a.1.1', 1);//此处会创建数组 `D.get('a')`的输出如下: { 1: [1], b:1, c:[undefined ,1] } Data可以将传入的键,智能转换为对应的空间,支持对象和数组。 ##sub* sub方法是Data的核心方法,用来订阅消息,订阅指定键值的指定事件,在对应的值发生变化时,会得到通知(当传入对象和数组时,消息会下发到其子元素)。 - type {String} 订阅消息的类型 (可选值:set, add, update, delete 分别代表 设置,添加,更新,删除,其中set是通用类型,其他三个为细分类型,并且互斥) - key {String} 订阅消息的键值 - callback {Function} 消息接受函数 - return {Number} 消息的同意id用于取消订阅事件用 demo D.sub('set', 'a', function (e) {console.log(e)}); D.set('a', 1);//a值更新,会调用回调函数 ###e - type {String} 消息的类型 - key {String} 消息的建 - data {val} 设置的值 ##unsub 取消订阅的消息。 - type {String} 取消订阅消息的类型 (可选值:set, add, update, delete 分别代表 设置,添加,更新,删除,其中set是通用类型,其他三个为细分类型,并且互斥) - key {String} 取消订阅消息的键值 - id {Number} [可选] sub是返回的消息的id - return {Bollean} 是否取消成功 若id为空则会删除所有对应键值和类型的所有事件。 demo var id = D.sub('set', 'a', function (e) {console.log(e)}); D.set('a', 1);//a值更新,会调用回调函数 D.unsub('set', 'a', id); D.set('a', 1);//不会在收到通知 ##注意事项 由于Data设计之初希望支持跨平台,所以要支持ecmascript类型数据,Data希望放入的是数据,期望的是原生数据,支持 Number,Bollean,String,Object,null,undefined,Array。对于Object和Array会是其深拷贝值,并且会创造层级。 对于其他类型对象js都默认为值类型,如dom节点,仅简单赋值其引用,所以消息无法下发到dom的子元素上,但get接口可以取到其子元素。其他类型对象还包括: - window - document - dom - dom list - node list 请不要将复杂对象和引用自身的对象放入Data中,会造成性能的严重下降,和不可预知的问题。复杂对象包括如下: - jquery对象 建议放入原生数据,对于jquery对象可传入其查询字符串。