Created
December 4, 2012 06:21
-
-
Save Mr0grog/4201233 to your computer and use it in GitHub Desktop.
Object.defineProperties modeled in JS
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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