Skip to content

Instantly share code, notes, and snippets.

@Mr0grog
Created December 4, 2012 06:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Mr0grog/4201233 to your computer and use it in GitHub Desktop.
Save Mr0grog/4201233 to your computer and use it in GitHub Desktop.
Object.defineProperties modeled in JS
Object.defineProperties = function(O, Properties) {
// 1. If Type(O) is not Object throw a TypeError exception.
if (typeof(O) !== "object" || O == null) {
throw TypeError("Object.defineProperties called on non-object");
}
// 2. Let props be ToObject(Properties)
var props = Object(Properties); // not *exactly* the same, but similar enough
// 3. Let names be an internal list containing the names of each enumerable own property of props.
var names = Object.getOwnPropertyNames(props);
// 4. Let descriptors be an empty internal List.
var descriptors = [];
// 5. For each element P of names in list order,
names.forEach(function(P) {
// 5.a Let descObj be the result of calling the [[Get]] internal method of props with P as the argument.
var descObj = props[P];
// 5.b Let desc be the result of calling ToPropertyDescriptor with descObj as the argument.
// the following is literally what ToPropertyDescriptor does. It's *really* simple.
var desc = {};
if (descObj.hasOwnProperty("enumerable")) desc.enumerable = Boolean(descObj.enumerable);
if (descObj.hasOwnProperty("configurable")) desc.configurable = Boolean(descObj.configurable);
if (descObj.hasOwnProperty("value")) desc.value = descObj.value;
if (descObj.hasOwnProperty("writable")) desc.writable = Boolean(descObj.writable);
if (descObj.hasOwnProperty("get")) {
if (typeof(descObj.get) !== "function") {
throw TypeError("Getter must be a function");
}
desc.get = descObj.get;
}
if (descObj.hasOwnProperty("set")) {
if (typeof(descObj.set) !== "function") {
throw TypeError("Setter must be a function");
}
desc.set = descObj.set;
}
if ((desc.get || desc.set) && (desc.hasOwnProperty("value") || desc.hasOwnProperty("writable"))) {
throw TypeError("value or writable cannot be specified if a getter or setter is specified")
}
// 5.c Append the pair (a two element List) consisting of P and desc to the end of descriptors.
descriptors.push([P, desc]);
});
// 6. For each pair from descriptors in list order,
descriptors.forEach(function(pair) {
// 6.a Let P be the first element of pair.
var P = pair[0];
// 6.b Let desc be the second element of pair.
var desc = pair[1];
// 6.c Call the [[DefineOwnProperty]] internal method of O with arguments P, desc, and true.
// DefineOwnProperty is an internal method not accessible from JS, but we'll pretend it exists here
// this is a lot like: Object.defineProperty(O, P, desc);
O.DefineOwnProperty(P, desc, true);
});
// 7. Return O.
return O;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment