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.

\$\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);
           }
        }
     }
\$\endgroup\$
5
  • \$\begingroup\$ Object.prototype.hasOwnProperty.call(key, k); otherwise you have unexpected behavior if your data contains a hasOwnProperty property. \$\endgroup\$
    – Kevin Reid
    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\$
    – jfriend00
    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\$
    – Kevin Reid
    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\$
    – jfriend00
    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\$
    – js-coder
    Apr 12, 2012 at 16:29

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.