Last active
December 17, 2015 06:18
-
-
Save ryasmi/5564105 to your computer and use it in GitHub Desktop.
A way to extend functionality using prototypes.
This file contains hidden or 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
// A function to create non-enumerable functions in specific scopes. | |
var func = (function (defineProp, undefined) { | |
"use strict"; | |
// In older browsers Object.defineProperty is not available. | |
// In IE8 Object.defineProperty can only be used on DOM elements. | |
var initProp = (!defineProp || !defineProp({}, "ie8Test", {value: false})) ? | |
function () {} : | |
function (name, scope, write, enumer, config) { | |
enumer = (enumer === undefined ? false : enumer); | |
write = (write === undefined ? true : write); | |
config = (config === undefined ? true : config); | |
defineProp(scope, name, { | |
writable: write, | |
enumerable: enumer, | |
configurable: config | |
}); | |
}; | |
return function (name, fn, scope, overwrite, enumer, write, config) { | |
scope = scope || this; | |
if (name === "length" && scope === Array.prototype) { | |
console.warn("Overwriting length does not work in all browsers!"); | |
return undefined; | |
} | |
if (scope[name] && !overwrite) { | |
console.warn("Cannot overwrite property!"); | |
return undefined; | |
} | |
scope[name] = fn; | |
initProp(name, scope, write, enumer, config); | |
return scope[name]; | |
}; | |
}(Object.defineProperty)); | |
// Source (1): https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/defineProperty | |
// Source (2): http://ejohn.org/blog/ecmascript-5-objects-and-properties/ | |
// Value. Contains the value of the property. | |
// Get. The function that will be called when the value of the property is accessed. | |
// Set. The function that will be called when the value of the property is changed. | |
// Writable. If false, the value of the property can not be changed. | |
// Configurable. If false, any attempts to delete the property or change its attributes (Writable, Configurable, or Enumerable) will fail. | |
// Enumerable. If true, the property will be iterated over when a user does for (var prop in obj){} (or similar). |
This file contains hidden or 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
var func=function(e,r){"use strict" | |
var n=e&&e({},"ie8Test",{value:!1})?function(n,t,o,i,a){i=i===r?!1:i,o=o===r?!0:o,a=a===r?!0:a,e(t,n,{writable:o,enumerable:i,configurable:a})}:function(){} | |
return function(e,t,o,i,a,u,c){return o=o||this,"length"===e&&o===Array.prototype?(console.warn("Overwriting length does not work in all browsers!"),r):o[e]&&!i?(console.warn("Cannot overwrite property!"),r):(o[e]=t,n(e,o,u,a,c),o[e])}}(Object.defineProperty) |
I'm using undefined
in some cases because I'm not defining what the function should do in that case. This also conforms to the general style in which JavaScript is written. Finally it is a lot quicker and easier (in coding terms) to test if something is undefined than it is to catch an error, so undefined has been used for convenience in this case.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Using console.warn for development and testing purposes. When not developing or testing all methods of the console should be set to empty functions.