Simulating ES6 Symbols In ES5
Symbols, previously known as Names, are a new way to add real private properties to a generic object.
In any case it looks like private symbols will be a better way to go than WeakMap when all we would like to have is a private property. Symbols can be used as Enums too, being unique as any other object is.
Bear in mind, regardless being a hack, this script does not actually cause any problem to any other script or library you are using today but it needs ES5 compatible browsers such all mobiles plus all desktops and IE9 or greater.
In few words symbol makes possible to attach properties directly without passing through a WeakMap. A similar behavior could be obtained indeed via WeakMaps:
// basic Symbol example
var BehindTheScene = (function(){
var symbol = new Symbol;
function BehindTheScene(){
this[symbol] = {};
}
BehindTheScene.prototype.get = function(k) {
return this[symbol][k];
};
BehindTheScene.prototype.set = function(k, v) {
return this[symbol][k] = v;
};
return BehindTheScene;
}());
var obj = new BehindTheScene;
obj.set('key', 123);
obj.key; // undefined
obj.get('key'); // 123
// similar WeakMap example
var BehindTheScene = (function(){
var wm = new WeakMap;
function BehindTheScene(){
wm.set(this, {});
}
BehindTheScene.prototype.get = function(k) {
return wm.get(this)[k];
};
BehindTheScene.prototype.set = function(k, v) {
return wm.get(this)[k] = v;
};
return BehindTheScene;
}());
var obj = new BehindTheScene;
obj.set('key', 123);
obj.key; // undefined
obj.get('key'); // 123
Why Symbols
To be honest I am not sure but these somehow bring some magic to the object rather than wrapping magic around it, as it is for the WeakMap example, so at least performance should be better ... right? Well, the current shim VS shim says thatindexOf()
is faster than an implicit toString()
: check this test out by yourself ;)In any case it looks like private symbols will be a better way to go than WeakMap when all we would like to have is a private property. Symbols can be used as Enums too, being unique as any other object is.
Simulating Symbols In Current ES5 JavaScript
As easy as this:A very basic example here:
var Symbol;
if (!Symbol) {
Symbol = (function(Object){
// (C) WebReflection Mit Style License
var ObjectPrototype = Object.prototype,
defineProperty = Object.defineProperty,
prefix = '__simbol' + Math.random() + '__',
id = 0;
function get(){/*avoid set w/out get prob*/}
function Symbol() {
var __symbol__ = prefix + id++;
defineProperty(
ObjectPrototype,
this._ = __symbol__,
{
enumerable: false,
configurable: false,
get: get, // undefined
set: function (value) {
defineProperty(this, __symbol__, {
enumerable: false,
configurable: true,
writable: true,
value: value
});
}
}
);
}
defineProperty(Symbol.prototype, 'toString', {
enumerable: false,
configurable: false,
writable: false,
value: function toString() {
return this._;
}
});
return Symbol;
}(Object));
}
Of course, you can try also the very first example, the one with a shared, private, symbol variable, that will simply work as expected :)
var sym = new Symbol;
var o = {};
o[sym]; // undefined
o[sym] = 123;
console.log(o[sym]); // 123
for (var k in o) {
console.log(k); // nothing at all
// there is nothing to for/in
}
delete o[sym]; // true
Bear in mind, regardless being a hack, this script does not actually cause any problem to any other script or library you are using today but it needs ES5 compatible browsers such all mobiles plus all desktops and IE9 or greater.
Comments
Post a Comment