Come vedi qui la proprietà length è numerabile e configurabile... eppure questo non l'avresti mai potuto fare senza il defineProperty...
codice:
var oggetto = {};
Object.defineProperty(oggetto, "length", {
get: function() {
nLen = 0;
for (var sKey in this) { nLen++; }
return nLen;
},
enumerable: true,
configurable: true
});
alert(oggetto.length);
oggetto.ciao = "mondo";
alert(oggetto.length);
oggetto.tizio = "caio";
alert(oggetto.length);
delete oggetto.tizio;
alert(oggetto.length);
Quest'esempio è al limite della stupidità... ma nel seguente sfortunato tentativo di creare un codice di compatibilità dell'oggetto nativo localStorage per IE 8 (sfortunato perché IE 8 supporta il defineProperty in maniera incompatibile con questo script) l'attribuzione di funzioni get e set è stata fondamentale per far sì che l'oggetto localStorage si sincronizzasse con i cookies a ogni invocazione:
codice:
if (!window.localStorage) {
Object.defineProperty(window, "localStorage", new (function () {
var aKeys = [], oStorage = {};
Object.defineProperty(oStorage, "getItem", {
value: function (sKey) { return this[sKey]; },
writable: false,
configurable: false,
enumerable: false
});
Object.defineProperty(oStorage, "key", {
value: function (nKeyId) { return aKeys[nKeyId]; },
writable: false,
configurable: false,
enumerable: false
});
Object.defineProperty(oStorage, "setItem", {
value: function (sKey, sValue) {
if(!sKey) { return; }
document.cookie = escape(sKey) + "=" + escape(sValue) + "; path=/";
},
writable: false,
configurable: false,
enumerable: false
});
Object.defineProperty(oStorage, "length", {
get: function () { return aKeys.length; },
configurable: false,
enumerable: false
});
Object.defineProperty(oStorage, "removeItem", {
value: function (sKey) {
if(!sKey) { return; }
var sExpDate = new Date();
sExpDate.setDate(sExpDate.getDate() - 1);
document.cookie = escape(sKey) + "=; expires=" + sExpDate.toGMTString() + "; path=/";
},
writable: false,
configurable: false,
enumerable: false
});
this.get = function () {
var iThisIndx;
for (var sKey in oStorage) {
iThisIndx = aKeys.indexOf(sKey);
if (iThisIndx === -1) { oStorage.setItem(sKey, oStorage[sKey]); }
else { aKeys.splice(iThisIndx, 1); }
delete oStorage[sKey];
}
for (aKeys; aKeys.length > 0; aKeys.splice(0, 1)) { oStorage.removeItem(aKeys[0]); }
for (var iCouple, iKey, iCouplId = 0, aCouples = document.cookie.split(/;\s*/); iCouplId < aCouples.length; iCouplId++) {
iCouple = aCouples[iCouplId].split("=");
if (iCouple.length > 1) {
oStorage[iKey = unescape(iCouple[0])] = unescape(iCouple[1]);
aKeys.push(iKey);
}
}
return oStorage;
};
this.configurable = false;
this.enumerable = true;
})());
}