Skip to content

Instantly share code, notes, and snippets.

@WebReflection
Created October 15, 2011 11:01
Show Gist options
  • Save WebReflection/1289401 to your computer and use it in GitHub Desktop.
Save WebReflection/1289401 to your computer and use it in GitHub Desktop.
A simplified and intuitive way to define objects properties
(function (Object) {
/**
* @name Object.prototype.define
* @description A simplified and intuitive way to define objects properties.
* @requires Object.defineProperty, Array.prototype.forEach (native or shimmed)
* @author Andrea Giammarchi (@WebReflection)
* @license Mit Style
*/
// function reused for every defined property
function assign(key, i, descriptor) {
// if descriptor is not present
// last valid one is recycled
// handy to define multiple properties
// with the same type
if (i in this.d) {
last = i;
}
descriptor = this.d[last];
// if descriptor is not an object
if (typeof descriptor != "object" || descriptor == null) {
// the descriptor is created runtime
descriptor = {
value: descriptor
};
}
// by default defined properties should not be redefined
// otherwise there could be unexpected results
if (!hasOwnProperty.call(descriptor, "configurable")) {
descriptor.configurable = false;
}
// by default properties are writeable
// unless the property is not a method
// so that methods cannot be changed runtime
if (
!hasOwnProperty.call(descriptor, "writable") &&
!(
hasOwnProperty.call(descriptor, "set") ||
hasOwnProperty.call(descriptor, "get")
)
) {
descriptor.writable = typeof descriptor.value != "function";
}
// by convention all property names that starts with underscore
// are considered not enumerable
if (!hasOwnProperty.call(descriptor, "enumerable")) {
descriptor.enumerable = key.charAt(0) != "_";
}
// we can define now the property after all handy checks
defineProperty(this.r, key, descriptor);
}
var // private shortcuts shared across this scope
defineProperty = Object.defineProperty,
hasOwnProperty = {}.hasOwnProperty,
a = [],
concat = a.concat,
last = 0,
define = "define"
;
// if not defined already ...
define in Object.prototype || defineProperty(
// set the method and do not let others change it
Object.prototype,
define,
{
enumerable: false,
configurable: false,
writable: false,
value: function defining(
keys, // String or Array of Strings
descriptors // Object or Array of Objects
) {
concat.call(a, keys).forEach(
assign,
{
// reference
r: this,
// descriptors
d: concat.call(a, descriptors)
}
);
last = 0;
return this;
}
}
);
}(Object));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment