2
\$\begingroup\$

I wrote a small JavaScript libary that aims to simplify JavaScript cookies. You can find the code on Github: https://github.com/js-coder/cookie.js I tested it in various browsers and it seems to work everywhere.

It's not a lot of code so I'll insert it here as well: I updated the code quite a bit so I posted the new version below.

(function (undefined) {
 var isArray = Array.isArray || function (value) { // check if value is an array created with [] or new Array
 return Object.prototype.toString.call(value) === '[object Array]';
 },
 isPlainObj = function (value) { // check if value is an object that was created with {} or new Object
 return Object.prototype.toString.call(value) === '[object Object]';
 },
 getKeys = Object.keys || function (obj) { // Object.keys polyfill
 var keys = [],
 key = '';
 for (key in obj) {
 if (obj.hasOwnProperty(key)) keys.push(key);
 }
 return keys;
 },
 retrieve = function (value, fallback) { // return fallback if the value is undefined, otherwise return value
 return value === undefined ? fallback : value;
 },
 _cookie = {
 set: function (key, value, options) {
 if (isPlainObj(key)) {
 for (var k in key) {
 if (key.hasOwnProperty(k)) this.set(k, key[k]);
 }
 } else {
 options = options || {};
 var expires = options.expires || '',
 expiresType = typeof(expires),
 path = options.path ? ';path=' + options.path : '',
 domain = options.domain ? ';domain=' + options.domain : '',
 secure = options.secure ? ';secure' : '';
 if (expiresType === 'string' && expires !== '') expires = ';expires=' + expires;
 else if (expiresType == 'number') { // this is needed because IE does not support max-age
 var d = new Date;
 d.setTime(d.getTime() + expires);
 expires = ';expires=' + d.toGMTString();
 } else if (expires.hasOwnProperty('toGMTString')) expires = ';expires=' + expires.toGMTString();
 document.cookie = key + '=' + escape(value) + expires + path + domain + secure;
 }
 return this; // return the _cookie object to allow chaining
 },
 remove: function (keys) {
 keys = isArray(keys) ? keys : arguments;
 for (var i = 0, length = keys.length; i < length; i++) {
 this.set(keys[i], '', {
 expires: -60 * 60 * 24
 });
 }
 return this; // return the _cookie object to allow chaining
 },
 empty: function () {
 return this.remove(getKeys(this.all())); // return the _cookie object to allow chaining
 },
 get: function (key, fallback) {
 fallback = fallback || undefined;
 if (isArray(key)) {
 var result = {},
 cookies = this.all();
 for (var i = 0, l = key.length; i < l; i++) {
 var value = key[i];
 result[value] = retrieve(cookies[value], fallback);
 }
 return result;
 } else {
 var cookies = this.all();
 return retrieve(cookies[key], fallback);
 }
 },
 all: function () {
 if (document.cookie == '') return {};
 var match = document.cookie.split('; '),
 results = {};
 for (var i = 0, l = match.length; i < l; i++) {
 var tmp = match[i].split('=');
 results[tmp[0]] = unescape(tmp[1]);
 }
 return results;
 },
 enabled: function () {
 var ret = cookie.set('a', 'b').get('a') === 'b';
 cookie.remove('a');
 return ret;
 }
 },
 cookie = function (key, fallback) {
 return _cookie.get(key, fallback);
 },
 methods = ['set', 'remove', 'empty', 'get', 'all', 'enabled'];
 for (var i = 0, l = methods.length; i < l; i++) { // copy all _cookie methods to cookie
 var method = methods[i];
 cookie[method] = _cookie[method];
 }
 window.cookie = cookie;
}());

You can find the documentation here: https://github.com/js-coder/cookie.js/blob/master/readme.md

I would love to know how I can improve the code or the API.

asked Apr 4, 2012 at 19:30
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

I think you want to pass on the options argument and filter with hasOwnProperty() so inside of the .set() method this:

 if (isPlainObj(key)) {
 for (var k in key) {
 this.set(k, key[k]);
 }
 }

becomes this:

 if (isPlainObj(key)) {
 for (var k in key) {
 if (key.hasOwnProperty(k)) {
 this.set(k, key[k], options);
 }
 }
 }
answered Apr 4, 2012 at 19:45
\$\endgroup\$
5
  • \$\begingroup\$ Object.prototype.hasOwnProperty.call(key, k); otherwise you have unexpected behavior if your data contains a hasOwnProperty property. \$\endgroup\$ Commented Apr 8, 2012 at 18:16
  • \$\begingroup\$ @KevinReid - if an object has its own override property called hasOwnProperty, then it would seem that it intends to override it. If we always followed your suggestion, we'd never use a native method of an object, we'd always refer to everything from Object.prototype. \$\endgroup\$ Commented Apr 8, 2012 at 18:34
  • \$\begingroup\$ I prefer to distinguish between objects-as-data-structures (which this is intending to be as it doesn't read inherited properties etc.) and objects-as-OO with methods and properties, where inheritance is not rejected. \$\endgroup\$ Commented Apr 8, 2012 at 22:55
  • \$\begingroup\$ @KevinReid - But, JS doesn't have data only objects. An object is an object and every object has methods which one should be free to use. I understand the point you're making, but I don't think that's the way JS was designed to be use. You are free to use it that way yourself, I guess. \$\endgroup\$ Commented Apr 9, 2012 at 0:22
  • \$\begingroup\$ @jfriend00 I agree with you. BTW I fixed this with the latest update on github. :) github.com/js-coder/cookie.js/blob/master/cookie.js \$\endgroup\$ Commented Apr 12, 2012 at 16:29

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.