Для браузеров, реализующих этот Object.defineProperty()метод, приведенный ниже код генерирует и возвращает функцию, которую можно привязать к любому объекту, которым вы владеете.
Преимущество этого подхода в том, что он не расширяется Object.prototype.
Код работает, проверяя, имеет ли данный объект __objectID__свойство, и определяя его как скрытое (неперечисляемое) свойство, доступное только для чтения, если нет.
Таким образом, он защищен от любых попыток изменить или переопределить obj.__objectID__свойство только для чтения после того, как оно было определено, и последовательно выдает приятную ошибку вместо тихой ошибки.
Наконец, в весьма крайнем случае, когда __objectID__для данного объекта уже был определен какой-то другой код , это значение просто будет возвращено.
var getObjectID = (function () {
var id = 0; // Private ID counter
return function (obj) {
if(obj.hasOwnProperty("__objectID__")) {
return obj.__objectID__;
} else {
++id;
Object.defineProperty(obj, "__objectID__", {
/*
* Explicitly sets these two attribute values to false,
* although they are false by default.
*/
"configurable" : false,
"enumerable" : false,
/*
* This closure guarantees that different objects
* will not share the same id variable.
*/
"get" : (function (__objectID__) {
return function () { return __objectID__; };
})(id),
"set" : function () {
throw new Error("Sorry, but 'obj.__objectID__' is read-only!");
}
});
return obj.__objectID__;
}
};
})();