{"_id":"redefine","_rev":"31-743ce46cb663334e3b5415f6fb950740","name":"redefine","description":"A lightweight utility for ES6 like classes and an easier ES5 aware object properties definition introducing new, performance oriented, patterns.","dist-tags":{"latest":"0.2.1"},"versions":{"0.1.0":{"name":"redefine","version":"0.1.0","description":"A lightweight utility for an easier ES5 aware object properties definition introducing new, performance oriented, patterns.","homepage":"https://github.com/WebReflection/redefine","keywords":["ES5","defineProperty","defineProperties","Object","create","inheritance","OOP"],"licenses":[{"type":"MIT","url":"http://mths.be/mit"}],"author":{"name":"Andrea Giammarchi","email":"andrea.giammarchi@gmail.com","url":"http://webreflection.blogspot.com/"},"repository":{"type":"git","url":"git://github.com/WebReflection/redefine.git"},"main":"./src/redefine.js","engines":["node","rhino"],"dependencies":{},"devDependencies":{},"optionalDependencies":{},"_id":"redefine@0.1.0","dist":{"shasum":"8b606c160f310f49549682bcf701ad13989f9394","tarball":"https://registry.npmjs.org/redefine/-/redefine-0.1.0.tgz","integrity":"sha512-FIZ3pfYXI7XR1TOtifs/DYiJynSmEPIIjc/eL19Urhh/IemmOY9RnN1C/NbLMMPbhDKh5b5zsI0RiwQU7Sz51Q==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDKieLCKpinX9T7Slh4GXQlho3DEWgeDYyLz7VA1TzSPAiBcdJx3c5qWUSPRxhB0YPaI60Az5CjGlnCbUr4ufxF3gQ=="}]},"_npmVersion":"1.2.0","_npmUser":{"name":"webreflection","email":"andrea.giammarchi@gmail.com"},"maintainers":[{"name":"webreflection","email":"andrea.giammarchi@gmail.com"}],"directories":{}},"0.1.1":{"name":"redefine","version":"0.1.1","description":"A lightweight utility for an easier ES5 aware object properties definition introducing new, performance oriented, patterns.","homepage":"https://github.com/WebReflection/redefine","keywords":["ES5","defineProperty","defineProperties","Object","create","inheritance","OOP"],"licenses":[{"type":"MIT","url":"http://mths.be/mit"}],"author":{"name":"Andrea Giammarchi","email":"andrea.giammarchi@gmail.com","url":"http://webreflection.blogspot.com/"},"repository":{"type":"git","url":"git://github.com/WebReflection/redefine.git"},"main":"./src/redefine.js","engines":["node","rhino"],"dependencies":{},"devDependencies":{},"optionalDependencies":{},"_id":"redefine@0.1.1","dist":{"shasum":"df5e3cddf5d135fcde726716ea273f7a0b77fac8","tarball":"https://registry.npmjs.org/redefine/-/redefine-0.1.1.tgz","integrity":"sha512-JLzWsheNJO1VvwGA7tK1L8AEwYpNVy6FsGXbdKoeiT3WyK0j58RW8d9bjncTnuWOBu1CEwi2PivrFLxdOXNRZw==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCf80SlmLX/+6W/Tbh+GLlaIFoe4cF/+5fEYIOhRUOJKAIgA4Oixw0dNJOToYT3fM/YFhAhJwVDELvbwXD0AJFp9Eo="}]},"_npmVersion":"1.2.0","_npmUser":{"name":"webreflection","email":"andrea.giammarchi@gmail.com"},"maintainers":[{"name":"webreflection","email":"andrea.giammarchi@gmail.com"}],"directories":{}},"0.1.2":{"name":"redefine","version":"0.1.2","description":"A lightweight utility for an easier ES5 aware object properties definition introducing new, performance oriented, patterns.","homepage":"https://github.com/WebReflection/redefine","keywords":["ES5","defineProperty","defineProperties","Object","create","inheritance","OOP"],"licenses":[{"type":"MIT","url":"http://mths.be/mit"}],"author":{"name":"Andrea Giammarchi","email":"andrea.giammarchi@gmail.com","url":"http://webreflection.blogspot.com/"},"repository":{"type":"git","url":"git://github.com/WebReflection/redefine.git"},"main":"./src/redefine.js","engines":["node","rhino"],"dependencies":{},"devDependencies":{},"optionalDependencies":{},"_id":"redefine@0.1.2","dist":{"shasum":"734db82d87341fbb04e89077248cb1a4acd2a54d","tarball":"https://registry.npmjs.org/redefine/-/redefine-0.1.2.tgz","integrity":"sha512-ayvhsKYlwNj4rYdvE5CvvbVK2eaY1uCXxkbkWOFOs7VT7zs+xmTfLDJ/CVL3I9NxZT5NQFhU6LJSWSXHtbjRdA==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAPLv+/n9gdOaX0yCG+ycWbuCSTvfUe3kGsDNHEmIGMXAiBXi3E9FCmkGU37+0ReT+fO66knhUD3g8FAGk/eXhs7VA=="}]},"_npmVersion":"1.2.0","_npmUser":{"name":"webreflection","email":"andrea.giammarchi@gmail.com"},"maintainers":[{"name":"webreflection","email":"andrea.giammarchi@gmail.com"}],"directories":{}},"0.1.3":{"name":"redefine","version":"0.1.3","description":"A lightweight utility for an easier ES5 aware object properties definition introducing new, performance oriented, patterns.","homepage":"https://github.com/WebReflection/redefine","keywords":["ES5","defineProperty","defineProperties","Object","create","inheritance","OOP"],"licenses":[{"type":"MIT","url":"http://mths.be/mit"}],"author":{"name":"Andrea Giammarchi","email":"andrea.giammarchi@gmail.com","url":"http://webreflection.blogspot.com/"},"repository":{"type":"git","url":"git://github.com/WebReflection/redefine.git"},"main":"./src/redefine.js","engines":["node","rhino"],"dependencies":{},"devDependencies":{},"optionalDependencies":{},"_id":"redefine@0.1.3","dist":{"shasum":"8f8b44fb63b69e67aad6606155cdcd80c2518bdf","tarball":"https://registry.npmjs.org/redefine/-/redefine-0.1.3.tgz","integrity":"sha512-grNFxiElY8rwrwAhoDIrOyF0v3wEKgRz2MunMINYkcnQjMdnANyH3JZdRuZmx5zW48lHl8+OcIlxnV3LXmMtlw==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIA4qoKlidd4VN3kkdrmmqsYCD/C8Kn/4a32LgZGifr0jAiAJM/105HaEN6P00eItMrpKQ7cWNN8TJBka7UJnDBGqdQ=="}]},"_npmVersion":"1.2.0","_npmUser":{"name":"webreflection","email":"andrea.giammarchi@gmail.com"},"maintainers":[{"name":"webreflection","email":"andrea.giammarchi@gmail.com"}],"directories":{}},"0.1.4":{"name":"redefine","version":"0.1.4","description":"A lightweight utility for an easier ES5 aware object properties definition introducing new, performance oriented, patterns.","homepage":"https://github.com/WebReflection/redefine","keywords":["ES5","defineProperty","defineProperties","Object","create","inheritance","OOP"],"licenses":[{"type":"MIT","url":"http://mths.be/mit"}],"author":{"name":"Andrea Giammarchi","email":"andrea.giammarchi@gmail.com","url":"http://webreflection.blogspot.com/"},"repository":{"type":"git","url":"git://github.com/WebReflection/redefine.git"},"main":"./src/redefine.js","engines":["node","rhino"],"dependencies":{},"devDependencies":{},"optionalDependencies":{},"_id":"redefine@0.1.4","dist":{"shasum":"d6ede2eb9fc317ce10e7f4b88fddf7330b28e2f2","tarball":"https://registry.npmjs.org/redefine/-/redefine-0.1.4.tgz","integrity":"sha512-1QyqE9CB5f4hAngE/sxiP1L6lutVt/TlB7k3mBkSo2Np64mJ4VZOaOHdd9LEarOt2us41bis433+OM+g2RNqlg==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBTXNjbT5KJlKzfRhcVR8PX7nstdwDPBklTh9i41chHsAiBIQfgPP8xKEes+yvPPT21YC8rEOurxVphRL/PdAY8Zgg=="}]},"_npmVersion":"1.2.0","_npmUser":{"name":"webreflection","email":"andrea.giammarchi@gmail.com"},"maintainers":[{"name":"webreflection","email":"andrea.giammarchi@gmail.com"}],"directories":{}},"0.1.6":{"name":"redefine","version":"0.1.6","description":"A lightweight utility for an easier ES5 aware object properties definition introducing new, performance oriented, patterns.","homepage":"https://github.com/WebReflection/redefine","keywords":["super","ES5","defineProperty","defineProperties","Object","create","inheritance","security","safe","mixin","Class","OOP"],"licenses":[{"type":"MIT","url":"http://mths.be/mit"}],"author":{"name":"Andrea Giammarchi","email":"andrea.giammarchi@gmail.com","url":"http://webreflection.blogspot.com/"},"repository":{"type":"git","url":"git://github.com/WebReflection/redefine.git"},"main":"./build/redefine.js","engines":["node","rhino"],"scripts":{"test":"node test/.test.js"},"dependencies":{"wru":">= 0.0.0"},"_id":"redefine@0.1.6","dist":{"shasum":"d48425792d5c53152b42b6f61c60a232bf4d2583","tarball":"https://registry.npmjs.org/redefine/-/redefine-0.1.6.tgz","integrity":"sha512-KooXv8huIDa8VVsJcmfpj2HIG+pB4lrRrg8AfS1XC8DectFyxn1gzqO1PJUHvEWrbHjZjmmXD3yWCM0SOKYb2A==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDy4yUIys6d+ioJtQbZlnDF7SKVEUghwRCbZUrtgk/vogIgQwnT0ntil+u0GVxq00N3SWVWId++vXlrl+UfvIyli8Q="}]},"_from":".","_npmVersion":"1.2.14","_npmUser":{"name":"webreflection","email":"andrea.giammarchi@gmail.com"},"maintainers":[{"name":"webreflection","email":"andrea.giammarchi@gmail.com"}],"directories":{}},"0.1.7":{"name":"redefine","version":"0.1.7","description":"A lightweight utility for an easier ES5 aware object properties definition introducing new, performance oriented, patterns.","homepage":"https://github.com/WebReflection/redefine","keywords":["super","ES5","defineProperty","defineProperties","Object","create","inheritance","security","safe","mixin","Class","OOP"],"licenses":[{"type":"MIT","url":"http://mths.be/mit"}],"author":{"name":"Andrea Giammarchi","email":"andrea.giammarchi@gmail.com","url":"http://webreflection.blogspot.com/"},"repository":{"type":"git","url":"git://github.com/WebReflection/redefine.git"},"main":"./build/redefine.js","engines":["node","rhino"],"scripts":{"test":"node test/.test.js"},"dependencies":{"wru":">= 0.0.0"},"_id":"redefine@0.1.7","dist":{"shasum":"36c7249f8483bdecb7c9b79c467818312e948f8b","tarball":"https://registry.npmjs.org/redefine/-/redefine-0.1.7.tgz","integrity":"sha512-6KwExAE7u/ATap2tLsN2VQtpgKHOM/fjdyz4F4hL6aoMXvwRYZlO0ZzvmklLdXYizOWf36VqXscrLe9Dloke5g==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCT6kh0CDKQXkZM3mgDjKcA4ZZzW4Iv9F+l61/yD4ZRvgIgQn7E/nYDblvZE7XryQSZLP/z3/cjnxatiXrOLollZwA="}]},"_from":".","_npmVersion":"1.2.14","_npmUser":{"name":"webreflection","email":"andrea.giammarchi@gmail.com"},"maintainers":[{"name":"webreflection","email":"andrea.giammarchi@gmail.com"}],"directories":{}},"0.1.8":{"name":"redefine","version":"0.1.8","description":"A lightweight utility for an easier ES5 aware object properties definition introducing new, performance oriented, patterns.","homepage":"https://github.com/WebReflection/redefine","keywords":["super","ES5","defineProperty","defineProperties","Object","create","inheritance","security","lazy","performance","safe","mixin","Class","OOP"],"licenses":[{"type":"MIT","url":"http://mths.be/mit"}],"author":{"name":"Andrea Giammarchi","email":"andrea.giammarchi@gmail.com","url":"http://webreflection.blogspot.com/"},"repository":{"type":"git","url":"git://github.com/WebReflection/redefine.git"},"main":"./build/redefine.js","engines":["node","rhino"],"scripts":{"test":"node test/.test.js"},"dependencies":{"wru":">= 0.0.0"},"_id":"redefine@0.1.8","dist":{"shasum":"e33f79ab4d20dd5be73ef2b8bb4bc27de64c7d3d","tarball":"https://registry.npmjs.org/redefine/-/redefine-0.1.8.tgz","integrity":"sha512-hdzcC3ZlYqUtQT1q1x5osHrL5AMDG8PPhKRwdQanil9KFGNOEM/SPWnHYXvdp45UdMnEpINGLNaVQgoXFU6X4w==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICvxsRwub0SEh+qBFKTmTQXjqYkkLtJ8IDQJ/DKLkuKwAiEAuN9TlYr0Ozm6Kwo2Cc759dBiKvSc/CFplMhLBgVov08="}]},"_from":".","_npmVersion":"1.2.17","_npmUser":{"name":"webreflection","email":"andrea.giammarchi@gmail.com"},"maintainers":[{"name":"webreflection","email":"andrea.giammarchi@gmail.com"}],"directories":{}},"0.1.9":{"name":"redefine","version":"0.1.9","description":"A lightweight utility for ES6 like classes and an easier ES5 aware object properties definition introducing new, performance oriented, patterns.","homepage":"https://github.com/WebReflection/redefine","keywords":["super","ES5","ES6","defineProperty","defineProperties","Object","create","inheritance","security","bind","bound","lazy","performance","safe","mixin","Class","OOP"],"licenses":[{"type":"MIT","url":"http://mths.be/mit"}],"author":{"name":"Andrea Giammarchi","email":"andrea.giammarchi@gmail.com","url":"http://webreflection.blogspot.com/"},"repository":{"type":"git","url":"git://github.com/WebReflection/redefine.git"},"main":"./build/redefine.js","engines":["node","rhino"],"scripts":{"test":"node test/.test.js"},"dependencies":{"wru":">= 0.0.0"},"_id":"redefine@0.1.9","dist":{"shasum":"a254a29400d735af0bf6a8c87af16a4181ad0e4f","tarball":"https://registry.npmjs.org/redefine/-/redefine-0.1.9.tgz","integrity":"sha512-oihZb7qKeUWqsk+QWWjMuRd1Buqf8QEnwpECb8Hm+I3O4wVwoYxV0EnNiom9yDoagUVxi5N8ccPRENaL/Co+/w==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCrLknzTGkgF/P7NwOwgqJgv9/tVwTK6IghZRXY5y9VVAIhAKzzB6j3oVNzoZi85RzDSdTo0ndRNFd37+L/gQbQ4jrm"}]},"_from":".","_npmVersion":"1.2.18","_npmUser":{"name":"webreflection","email":"andrea.giammarchi@gmail.com"},"maintainers":[{"name":"webreflection","email":"andrea.giammarchi@gmail.com"}],"directories":{}},"0.2.0":{"name":"redefine","version":"0.2.0","description":"A lightweight utility for ES6 like classes and an easier ES5 aware object properties definition introducing new, performance oriented, patterns.","homepage":"https://github.com/WebReflection/redefine","keywords":["super","ES5","ES6","defineProperty","defineProperties","Object","create","inheritance","security","bind","bound","lazy","performance","safe","mixin","Class","OOP"],"licenses":[{"type":"MIT","url":"http://mths.be/mit"}],"author":{"name":"Andrea Giammarchi","email":"andrea.giammarchi@gmail.com","url":"http://webreflection.blogspot.com/"},"repository":{"type":"git","url":"git://github.com/WebReflection/redefine.git"},"main":"./build/redefine.js","engines":["node","rhino"],"scripts":{"test":"node test/.test.js"},"dependencies":{"wru":">= 0.0.0"},"_id":"redefine@0.2.0","dist":{"shasum":"dd39cdc4d82bc9b0b9163222ffcd91e5f0d02322","tarball":"https://registry.npmjs.org/redefine/-/redefine-0.2.0.tgz","integrity":"sha512-BvMPKLMk6fzE8Jh4ieYWsAy4ziXe8g8l1InzVmtxhz1eibzX7qLEvkrjhw1Cx6e5kXHChwopEtae78fJ7ej/8A==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIErqYMC29cV8hF8dp+CZyPT0xa8V6g/JQyORuEgZ4OdWAiBAhiAsIxjoArX7eEo3UnQslp+wyu2Ctel/rxyW3PBVSQ=="}]},"_from":".","_npmVersion":"1.2.18","_npmUser":{"name":"webreflection","email":"andrea.giammarchi@gmail.com"},"maintainers":[{"name":"webreflection","email":"andrea.giammarchi@gmail.com"}]},"0.2.1":{"name":"redefine","version":"0.2.1","description":"A lightweight utility for ES6 like classes and an easier ES5 aware object properties definition introducing new, performance oriented, patterns.","homepage":"https://github.com/WebReflection/redefine","keywords":["super","ES5","ES6","defineProperty","defineProperties","Object","create","inheritance","security","bind","bound","lazy","performance","safe","mixin","Class","OOP"],"licenses":[{"type":"MIT","url":"http://mths.be/mit"}],"author":{"name":"Andrea Giammarchi","email":"andrea.giammarchi@gmail.com","url":"http://webreflection.blogspot.com/"},"repository":{"type":"git","url":"git://github.com/WebReflection/redefine.git"},"main":"./build/redefine.js","engines":["node","rhino"],"scripts":{"test":"node test/.test.js"},"devDependencies":{"wru":">= 0.0.0"},"gitHead":"7e8037c729e4ed8219ea06716582f3b913ab6420","bugs":{"url":"https://github.com/WebReflection/redefine/issues"},"_id":"redefine@0.2.1","_shasum":"e89ee7a6f24d19fff62590569332dc60380a89a3","_from":".","_npmVersion":"2.13.2","_nodeVersion":"0.12.7","_npmUser":{"name":"webreflection","email":"andrea.giammarchi@gmail.com"},"dist":{"shasum":"e89ee7a6f24d19fff62590569332dc60380a89a3","tarball":"https://registry.npmjs.org/redefine/-/redefine-0.2.1.tgz","integrity":"sha512-F5dHsehFWLqzMN/f1YiquC2WBLTqdBF3IgnWT9hlNOdu0u+of716H8GArop2i+yBBk0tdd9f61ay48QJxuZkcg==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC2YlkvWDgAvbP+XMbQYwIG4mZhTJsqhjjtKVLjOIc66AIge0Scjtp+e6Yt88pUtw4KFFLXue9QClGs9JhRF0cEiZM="}]},"maintainers":[{"name":"webreflection","email":"andrea.giammarchi@gmail.com"}]}},"readme":"redefine.js\n===========\na lightweight yet powerful ES5 utility.\n\n[![build status](https://secure.travis-ci.org/WebReflection/redefine.png 'travis')](http://travis-ci.org/WebReflection/redefine)\n\n## Obsolete\nThe most updated, future proof, actively maintained, and widely compatible way to define classes is [es-class](https://github.com/WebReflection/es-class#es-class).\n\nIf you are here to enrich prototypes, please have a look at `es-class`, it will most likely provide everything you need and  much more.\n\nIf you are here to be able to lazily assign properties to a generic object or prototype, please check [lazyval](https://github.com/WebReflection/lazyval#lazyval).\n\n\n\n### About Redefine JS\nThis ~1.5KB (minified and gzipped) framework brings the power of ES5 and ES6 features in node.js and all modern mobile or desktop browsers.\n\nMain features:\n\n  * **ES6** like **classes** definition with extra power via `mixin` and `bound` magic\n  * **ES5** **properties** definition without descriptors paranoia and prolix syntax\n  * **ES3** **friendly** and mostly compatible\n\nAll common tasks to organize your objects access, definition, and inheritance, can be achieved via `redefine.js` goodness.\n\n### Classes\nOne thing really frequent in JS world, one thing not so easy to get right if not familiar with ES5: the JavaScript **Class** concept from other OOP languages.\n\nWell, with tests included on top of all features, `redefine.Class(definition)` now offers a semantic utility to safely create classes in JavaScript.\n\n```JavaScript\nvar Lib = redefine.Class({\n\n  extend: SuperLib,  // inheritance\n\n  mixin: oneOrMoreObject, // mixin\n         Constructor\n\n  statics: {         // statics\n    someMethod: function () {},\n    someProperty: 0\n  },\n                      // common definition\n  method1: function () {},\n  property1: null\n\n                      // constructor\n  constructor: function Lib() {\n    //implicit initialization\n    // never invoked if extended via other classes\n  }\n});\n```\nAll properties tested and fully covered, included the very special case where you want to use `this.super(argN)` in inherited methods or constructor. No performance impact if you don't use it, not a single problem if you are under strict code and don't want to allow `callback.caller` access, you use what you want/need when you want/need, how easy is that? Enjoy! (now back to the problem ...)\n\n\n### The Problem\nES5 verbosity is not just annoying, is also *spaghetti prone*. The inability to group few descriptors together for one or more properties is inefficient too because of the amount of garbage we create at runtime to define all properties we need.\n\n```javascript\n// classic ES5 syntax\nObject.defineProperties(\n  SomeClass.prototype,\n  {\n    method: {\n      value: function () {\n        // the method\n      }\n    },\n    property: {\n      enumerable: true,\n      value: \"the property\"\n    }\n  }\n);\n```\n\nTo define one method and one property we have used 3 extra objects: the properties wrapper, and each property descriptor. In case we were planning to make a list of properties all enumerable, as well as we could decide for writable or configurable, we would have repeated that pattern all over, resulting in a giant piece of JavaScript that will look like `enumerable:true` and nothing else. We also have some difficulty to understand what is each property about because the way we are familiar with is this one:\n\n```javascript\n// the familiar JS approach\nSomeClass.prototype = {\n  method: function () {\n    // the method\n  },\n  property: \"the property\"\n};\n```\n\nAbove snippet is not just more elegant and clean, is also better at runtime and much easier to read. In ES5, as example, when we see a function is not necessarily because that is a method, it might be a getter or setter too so we have to pay a lot of attention when we look at the code.\n\n### The Solution\nSo why cannot we have the best from both worlds? An easy to read and naturally understand syntax with the ability to switch ES5 power *on or off on demand*?\n\n```javascript\n// redefine.js\nredefine(\n  SomeClass.prototype, {\n  method: function () {\n    // the method\n  },\n  property: \"the property\"\n});\n```\n\nThe best part about `redefine.js` is its **ambiguity free** approach, granted by hidden classes understood at definition time, a technique that lets us switch `power on` when and if needed. As example, the very first `Object.definePropeties` snippet is not just setting properties, is also defining one of them as `enumerable`.\n\n```javascript\n// identical to initial snippet\nredefine(\n  SomeClass.prototype, {\n  method: function () {\n    // the method\n  },\n  property: redefine.as({\n    enumerable: true,\n    value: \"the property\"\n  })\n});\n```\n\nThe powerful simplified API lets us define **defaults** too, so imagine we want that all properties should be `configurable`, `enumerable`, and `writable` because we expect exactly same *ES3* behavior. This is what you would be forced to do in ES5:\n\n```javascript\n// ES5 has no defaults\nObject.defineProperties(\n  SomeClass.prototype,\n  {\n    method: {\n      configurable: true,\n      enumerable: true,\n      writable: true,\n      value: function () {\n        // the method\n      }\n    },\n    property: {\n      configurable: true,\n      enumerable: true,\n      writable: true,\n      value: \"the property\"\n    }\n  }\n);\n```\n\nIt's kinda hard to tell anymore what is that code about, don't you agree? Now let's compare against `redefine()`\n\n```javascript\n// redefine.js\nredefine(\n  SomeClass.prototype,\n  {\n    method: function () {\n      // the method\n    },\n    property: \"the property\"\n  },\n\n  // optional 3rd argument for defaults\n  {\n    configurable: true,\n    enumerable: true,\n    writable: true\n  }\n);\n```\n\nWe focus on the definition of our meant behavior, rather than on each descriptor property. If we apply defaults in groups, the code will be much more organized too. Bear in mind that defaults can be overwritten by semantic `redefine.as()` definition.\n\n```javascript\nredefine(\n  object,\n  {\n    prop: as({\n      enumerable: false,\n      value: theValue\n    })\n  },\n  {\n    enumerable: true\n  }\n);\n```\n\n### A Simplified Object.create\nWe all have to consider that current descriptors verbosity and concept is [\"*trolling*\" major ECMAScript experts in the world](https://mail.mozilla.org/pipermail/es-discuss/2012-November/026716.html) too. `Object.create` is not natural for JS developers and it makes things more complex than ever. Same descriptors verbosity applied for what should be the `new function` substitute ... in this sense it was a failure! How about redefining objects from others?\n\n```javascript\n// ES5 Object.create\nvar instance = Object.create(\n  sourceObject,\n  {\n    name:\n    {\n      value: \"instance\"\n    },\n    age:\n    {\n      value: 34\n    },\n    toString:\n    {\n      value: function () {\n        // isn't the `this` ambiguous here ?\n        // I would expect to refer to the toString descriptor\n        return \"Hi, I am \" + this.name + \", and I am \" this.age;\n      }\n    }\n  }\n);\n\n// redefine.js\nvar instance = redefine.from(\n  sourceObject,\n  {\n    name: \"instance\",\n    age: 34,\n    toString: function () {\n      return \"Hi, I am \" + this.name + \", and I am \" this.age;\n    }\n  }\n);\n```\n\nI hope you agree that every time we define a method where `this` is used inside another context, as the descriptor is, looks so confusing!\nThe descriptor is just an object and it could be used differently in other pieces of logic so that if invoked a part everything will fail there.\n\nIn few words, `redefine.js` can also be **less ambiguous** than ES5!\n\n### Lazy Property Definition Pattern Included\nI have described this pattern in [The Power Of Getters](http://webreflection.blogspot.com/2013/01/the-power-of-getters.html) entry in my blog.\n\nHowever, these two comments left me with too many thoughts about ES5 and the fact that really is not easy to understand for developers.\n\n> **Adrien Risser** ... Andrea, every post of yours is a brainfuck! Understanding barely most of what you describe, I can't say I see how I would use all of or just a part of it in any project of mine.\n\nor even worst ...\n\n> **jonz** ... Right now this *syntax seems like obfuscation but the patterns it supports are what I've always wanted*, I wonder if it will ever become familiar.\n\nSo you are right guys, the way ES5 lets us implement amazing new patterns and possibilities is even hard to understand or imagine. This is why `redefine.js` comes with a pattern many other programming languages can only dream about: the memory efficient and performance oriented **inherited getter replaced on demand with a direct property access**! (BOOM, I know your mind just blown!)\n\n```javascript\n// what you would do today in ES3 classes\nfunction MyClass() {\n  this.handlersIMightNeed = {};\n  this.propertiesIMightLookFor = [];\n  this.stuffNotSureIfEvenUse = {};\n  this.methodThatShouldBindWhenNeeded =\n    this.method.bind(this);\n}\n```\n\nAbove snippet creates 4 extra objects per each instance of `MyClass`. This is a [memory disaster prone approach plus is really slow during instance creation](http://jsperf.com/the-power-of-getters-element) you can easily compare checking the *Element_Getter* results across all browsers and engines. We also force our syntax to be ES3 because if the prototype of MyClass would have been defined via `Object.defineProperties()` and these were not `configurable` or `writable`, this is what we should really do in order to have an equivalent behavior in our code.\n\n```javascript\n// what we should do if MyClass.prototype\n// was defined with these properties as defaults\nfunction MyClass() {\n  Object.defineProperty(this,\n    \"handlersIMightNeed\", {value: {}});\n  Object.defineProperty(this,\n    \"propertiesIMightLookFor\", {value: []});\n  Object.defineProperty(this,\n    \"stuffNotSureIfEvenUse\", {value: {}});\n  Object.defineProperty(this,\n    \"methodThatShouldBindWhenNeeded\",\n    {value: this.method.bind(this)});\n}\n```\n\nThis ain't going anywhere, and this is why ES5 is keeping developers far away from its goodness. So, how about `redefine.later()` to obtain the desired pattern ?\n\n```javascript\nvar later = redefine.later;\n// redefine.js lazy getter replacement\nfunction MyClass(){\n  // nothing to do here\n  // it cannot be faster!\n}\nredefine(\n  MyClass.prototype,\n  {\n    handlersIMightNeed: later(function(){\n      return {};\n    }),\n    propertiesIMightLookFor: later(function(){\n      return [];\n    }),\n    stuffNotSureIfEvenUse: later(function(){\n      return {};\n    }),\n    methodThatShouldBindWhenNeeded: later(function(){\n      return this.method.bind(this);\n    })\n  }\n);\n```\n\nThere, a **zero costs** runtime instance creation where all those properties will be assigned as direct properties, rather than getters, when and only if the instance is using, or better, accessing them. These properties are also all deletable by default, unless specified differently, so that it's easy to reset hard a property and reassign it later on when, and if, needed.\n\n### More Robust Than ES5\nThere is a potential hole in ES5 specifications about descriptors, inherited properties are considered too. This is an example of how to destroy any library I know based on ES5:\n\n```javascript\n// malicious code\nObject.prototype.get = function screwed(){\n  // deal with it\n};\nObject.prototype.configurable =\nObject.prototype.enumerable =\nObject.prototype.writable = true;\n\n// your code\nvar o = Object.defineProperty({}, \"key\", {value: \"value\"});\n```\n\n**TypeError** `Invalid property. 'value' present on property with getter or setter.`\n\nThis would never happen in `redefine.js` world.\n\n```javascript\nvar o = redefine({}, \"key\", \"value\");\no.key; // \"value\", all good\n```\n\nHappy coding!\n\n### API\n\n#### redefine(obj, properties)\nThis is the main function and the only exported object. It does basically one thing but it has different overloads to do that:\n\n  * `redefine(obj:Object, key:string, value:any[, defaults:Object]):Object`, returns the first argument and define a value straight forward using ES5 defaults unless specified differently.\nThis signature has these two kind of overloads\n  * `redefine(obj:Object, key:string, value:As[, defaults:Object]):Object`, returns the first argument and define a property `key` using `redefine.as({descriptor})` as value descriptor. `As` is an internal, private, class that overrides any default, if specified, or inherited behavior.\n  * `redefine(obj:Object, key:string, value:Later[, defaults:Object]):Object`, returns the first argument and define a property `key` as lazily accessed and replaced as direct property that could be deleted at any time in order to reuse the inherited getter. `Later` is an internal, private, class that overrides any default, if specified, or inherited behavior.\n  * `redefine(obj:Object, properties:Object[, defaults:Object])`, returns the first argument, it does exactly what other overloads do in this case looping through own properties in the specified `properties` Object.\n\n#### redefine.from(proto)\nThis semantic method is similar to ES5 `Object.create` except descriptors are those accepted by `redefine()` and `defaults` can be used as well.\n\n  * `redefine.from(source:object[, properties:Object[, defaults:Object]]):Object` returns a new instance where `source.isPrototypeOf(returnedObject)`. Please note `null` is possible too and the second argument, optional as optional is the third one, can be used to redefine properties.\n  * `redefine.from(Class:Function[, properties:Object[, defaults:Object]]):Object` returns an `instanceof Class`, using `Class.prototype` as extend.\n\nHere an example:\n\n```javascript\nvar son = redefine.from(\n  ClassName, {age: 123}\n);\nson.age; // 123\nson instanceof ClassName; // true\nClassName.prototype.isPrototypeOf(son); // true\n```\n\nCreating instances from classes is the most common pattern in JS but if it's really needed to extend a function , rather than its prototype, this method is not the best one but it's possible to hack this behavior, if really needed, in an ugly way such `function df(){} df.prototype = Class; var o = redefine.from(df);`. Highly discouraged, user defined instance of functions cannot be even invoked, just saying...\n\n#### redefine.as(descriptor)\nThis semantic method returns an `instanceof As` with properties specified in the `descriptor` addressed once at initialization time.\n\n```javascript\nvar ES3Like = redefine.as({\n  enumerable: true,\n  configurable: true,\n  writable: true\n});\n\n// later on, reused to define all ES3 classes\nredefine(\n  MyES3Class.prototype,\n  {... all properties here ...},\n  ES3Like // as defaults\n);\n```\n\n#### redefine.later(Object)\nThis semantic method returns an `instanceof Later` object which aim is to be recognized later on in order to define a lazy getter replacement with direct property access pattern, an innovative pattern described in [The Power Of Getters](http://webreflection.blogspot.com/2013/01/the-power-of-getters.html) post.\n\n```javascript\nvar setAsObjectLaterOn = redefine.later(function (){\n  return {};\n});\n\n// in some class\nredefine(\n  MyEvent.prototype,\n  {\n    handlers: setAsObjectLaterOn\n  }\n);\n\n// so that no property is created runtime\nvar me = new MyEvent;\n// but only, and once, when/if needed\nme.handlers.test = listener;\n```\n\nIt is possible to use a descriptor in order to overwrite the default configuration for this use case which is `{configurable:true, writable:false, enumerable:false}`. In this case, the `value` should be the callback able to return the lazily defined property.\n\n```javascript\nvar setAsObjectLaterOn = redefine.later({\n  writable: true,     //we want be able to change it later on\n  enumerable: true,   // shows up in for/in loops\n  configurable: false,// once define there's no way to delete it\n  value: function (){\n    return {};\n  }\n});\n```\n\nI see what you are thinking about: \"*What? How can those properties have value and writable if we are defining a getter?*\" Did I mention this method is called `later()` because is later that the property is define through the inherited getter ? :-)\n\n#### redefine.using(descriptor)\nThis is to simplify partial implementations. As example, to use redefine to create enumerable properties:\n\n```javascript\nvar enumerable = redefine.using({\n  enumerable: true\n});\n\n// any property we want\nvar o = enumerable({}, \"test\", 123);\no.propertyIsEnumerable(\"test\"); // true\no.test; // 123\n````\n\n### Libraries Compatibility\nThe `redefine.js` API is compatible with [Underscore](http://underscorejs.org) and [Lo-Dash](http://lodash.com) too as `_.redefine` utility. Bear in mind, **you don't need these libraries** at all, in fact `redefine.js` is completely dependencies free but in order to avoid global scope pollution the `redefine` function is defined into a global `_` object. If this is not present it is created, while if it's already there, is simply enriched.\n\nIn *node.js* you can use require\n\n    npm install redefine\n\n```javascript\nvar\n  redefine = require('redefine'),\n  // redefine = require('redefine').redefine, works too\n  as = redefine.as,\n  from = redefine.from,\n  later = redefine.later\n;\n```\n\n### Browsers And Engines Compatibility\nIt is possible to enhance redefine targets using some partial polyfill of ES5 `Object` methods such `create` or [inherit](https://gist.github.com/4397807) and `defineProperty`. However, this library is targeting all browsers supported by [jQuery 2.0](http://blog.jquery.com/2012/07/01/jquery-1-9-and-2-0-tldr-edition/) so here the list:\n\n  * Internet Explorer 9 and greater\n  * Chrome, and mobile\n  * Firefox, and mobile\n  * Opera, and mobile\n  * Safari, and mobile\n  * Webkit stock browsers for mobile\n  * node.js\n  * Rhino\n\nOther server side engines such **Ringo** should be supported too since these are compatible with ES5 and ES5.1. The best way to know if your device, browser, or server side JS engine is working is to [grab wru](https://github.com/WebReflection/wru) and run those tests :-)\n\n\n### 100% Code Coverage\nYou can check examples and all tests to `redefine()`, `redefine.as(descriptr)`, `redefine.later(function value(){})`, or `redefine.from(proto)` in [this redefine.js file](https://github.com/WebReflection/redefine/blob/master/test/redefine.js).\n\nTo launch tests in **node.js** simply this:\n\n    npm install wru\n    wru test/redefine.js\n\nTo launch tests in any browser simply do `open test.html` in OSX or just double click the test.html file. If your browser needs a web server in order to load files locally, simply this:\n\n    npm install polpetta\n    polpetta ./\n\nthen check [your localhost/test.html](http://127.0.0.1:1337/test.html) page and it should be green.\n\n\n### Shut Up And Give Me Code !\nYou can find the [source code here](https://github.com/WebReflection/redefine/blob/master/src/redefine.js) and the [minified version here](https://github.com/WebReflection/redefine/blob/master/build/redefine.js).\n\nAs you can see, once minzipped the library is **about 0.6 KB** and for an easier life enriched with new patterns I think is hard to expect a lighter utility.\n\n### De Facto Targets\nThese are those situations where you might want to use `redefine.js`\n\n  * `node.js` development, or generally speaking any ES5 capable server side environment. The fact `redefine.js` is more robust should be an extra reason to adopt it.\n  * Smartphones, since nowadays, all of them support ES5\n  * modern desktop browsers and modern libraries\n\nEnjoy!\n\n","maintainers":[{"name":"webreflection","email":"andrea.giammarchi@gmail.com"}],"time":{"modified":"2022-06-26T09:41:05.779Z","created":"2013-01-19T21:29:01.797Z","0.1.0":"2013-01-19T21:29:02.965Z","0.1.1":"2013-01-20T05:41:33.801Z","0.1.2":"2013-01-20T23:02:26.852Z","0.1.3":"2013-01-21T20:01:28.656Z","0.1.4":"2013-01-23T04:48:58.578Z","0.1.6":"2013-03-20T01:38:57.765Z","0.1.7":"2013-03-20T18:32:16.234Z","0.1.8":"2013-04-10T04:19:53.025Z","0.1.9":"2013-05-11T17:09:03.819Z","0.2.0":"2013-05-14T17:34:53.403Z","0.2.1":"2015-07-26T13:44:40.492Z"},"author":{"name":"Andrea Giammarchi","email":"andrea.giammarchi@gmail.com","url":"http://webreflection.blogspot.com/"},"repository":{"type":"git","url":"git://github.com/WebReflection/redefine.git"},"users":{"pje":true},"homepage":"https://github.com/WebReflection/redefine","keywords":["super","ES5","ES6","defineProperty","defineProperties","Object","create","inheritance","security","bind","bound","lazy","performance","safe","mixin","Class","OOP"],"bugs":{"url":"https://github.com/WebReflection/redefine/issues"},"readmeFilename":"README.md"}