The last week I explored some things about `localStorage'. The most
interesting and meanwhile confusing things are described in two
articles about `localStorage':

<URL: 
http://www.bennadel.com/blog/2105-Exploring-HTML5-s-localStorage-Persistent-Client-Side-Key-Value-Pairs.htm>
<URL: http://hacks.mozilla.org/2009/06/localstorage/>
"The easiest way to use localStorage is to treat it like a regular object:"

After reading these articles I start thinking about the setter and
getter of storage instance referred by `window.localStorage'. The
others questions are:

Should I treat `localStorage' as a regular object?
Does it safe if I do?

So I did some tests, to answer on my questions.
The test cases are in Firefox 3.6 under Debian.

What happens with `localStorage' object when I put new item in
associated list trough `setItem' method?

var hasOwnP = Object.prototype.hasOwnProperty,
    storage = window.localStorage;

storage.clear(); //Clear associated list

storage.setItem('foo', 'bar');
console.log(hasOwnP.call(storage, 'foo')); //true
console.log(storage.getItem('foo')); //bar

storage.setItem('setItem', 'bar');
console.log(hasOwnP.call(storage, 'setItem')); //false
console.log(storage.getItem('setItem')); //bar
console.log(typeof storage.setItem); //function

storage.setItem('hasOwnProperty', 'bar');
console.log(hasOwnP.call(storage, 'hasOwnProperty')); //false
console.log(storage.getItem('hasOwnProperty')); //bar
console.log(typeof storage.hasOwnProperty); //function

Obviously `setItem' checks the prototype chain of `localStorage' for
passed key. If key exist it does not add new own property to
`localStorage' object. Just put this key/value in associated list. The
interesting part is if passed key does not exist in the prototype
chain of `localStorage', then it creates new own property of
`localStorage' and put key/value in associated list.

Everything seems safe and clear, but what happens if I treat this
object as "regular" object?
var hasOwnP = Object.prototype.hasOwnProperty,
    storage = window.localStorage;

storage.clear(); //Clear associated list

storage.setItem = 'bar';
console.log(hasOwnP.call(storage, 'setItem')); //true
console.log(storage.getItem('setItem')); //bar
console.log(typeof storage.setItem); //string

storage.hasOwnProperty = 'bar';
console.log(hasOwnP.call(storage, 'hasOwnProperty')); //true
console.log(storage.getItem('hasOwnProperty')); //bar
console.log(typeof storage.hasOwnProperty); //string

Now the setter does not check for existence of these properties names
in the prototype chain of `localStorage'. It directly add them as own
properties and also add them as key in associated list with this
storage instance.

This answer on my two questions and the answer is, it's not really
safe to treat `localStorage' as regular object. When I have to add
key/value in the list I should use `setItem' method.

Lets see the getter:

var hasOwnP = Object.prototype.hasOwnProperty,
    storage = window.localStorage;

storage.clear(); //Clear associated list

storage.setItem('foo', 'bar');
console.log(storage.getItem('foo')); //bar as expected
console.log(typeof storage.foo); //string as expected

storage.setItem('setItem', 'bar');
console.log(storage.getItem('setItem')); //bar as expected
console.log(typeof storage.setItem); //function "unexpected"

As I explained when `setItem' has called with `key` which exist as
property name in the prototype chain of `localStorage' it will not
create new own property name of `localStorage' with this name. From
this point comes the "unexpected" result.

While in my example it's not really unexpected result, it can be if
there are third party extensions of `Object.prototype', because
`localStorage' inherit from `Object.prototype'.

var hasOwnP = Object.prototype.hasOwnProperty,
    storage = window.localStorage;

storage.clear();

Object.prototype.foo = function () {};

storage.setItem('foo', 'bar');
console.log(storage.getItem('foo')); //bar as expected
console.log(typeof storage.foo); //function


Hope this thread makes some clarifications the members of JSMentors!

-- 
To view archived discussions from the original JSMentors Mailman list: 
http://www.mail-archive.com/[email protected]/

To search via a non-Google archive, visit here: 
http://www.mail-archive.com/[email protected]/

To unsubscribe from this group, send email to
[email protected]

Reply via email to