A single function to make defining sets of properties simple.
You can use def in two ways. The first using the target object as a parameter
var define = require('def').define;
define(myObject, properties);
The second allows you to attach it to an object for self-defining. This is useful when used on prototypes for imbuing the ability to easily define properties on objects inheriting from it.
var def = require('def');
def.attach(myObject.prototype);
// or expose it to all objects
def.attach(Object.prototype);
Then it should be used directly on the target object which should have the properties, whether that object will be used as a prototype or a singleton.
myObj.def(function namedFunction(){});
// -> //gets name from function itself, can only be named in source or with eval, not dynamic
{ namedFunction: Function namedFunction }
myObj.def('myProp', 5000);
// -> // simple property, config/enum/write = true
{ myProp: 5000 }
myObj.def({
get myProp(){ return 5000; },
set myProp(val){ 'some setter logic'; }
});
// ->
{ myProp: [Getter/Setter] }
myObj.def('_hiddenProp', 'somevalue');
// -> //non-enumerable, invisible unless you use getOwnPropertyNames, '_' sliced
{ [hiddenProp]: 'somevalue' }
myObj.def(function $superImportantFunction(){});
// -> //non-configurable (no delete or redefine), '$' sliced
{ [superImportantFunction]: Function $superImportantFunction }
myObj.def('SOMECONSTANT', 'this value is constant');
// -> //non-writable (can still be changed using configurability, AKA delete and redefine)
{ SOMECONSTANT: 'this value is constant' }
myObj.def({
property1: 'simpleValue',
get prop2(){ return 'get/setter using non-backcompat syntax' },
set prop2(val){ this.powerLevel = 9001; },
_someFunc: function(){ console.log("can't effectively use named functions with a dict =(") }
});
// ->
{ property1: 'simplValue',
prop2: [Getter/Setter],
[someFunc]: Function }
myObj.def([
function firstFunction(){ console.log('whatever:' + this); },
function getSecrets(){ return getSecretsFromDB('teehee'); },
function setSecrets(val){ sendSecretsToDB(val); },
function _stealSecretsForBlackMarket(){ return getAllSecretsFromDB_unlogged(); },
]);
// ->
{ firstFunction: Function firstFunction,
Secrets: [Getter/Setter],
[stealSecretsForBlackMarket]: Function _stealSecretsForBlackMarket }
Private values are detected by the existence of an extra parameter on the get or set functions. These aren't valid getters and setters to JavaScript but they will be wrapped such that they share a private value inaccessible from anywhere else, but shared between the getter and setter functions. The private value is passed in each time, along with the passed in value for setters.
myObj.def({
myPrivate: {
get: function(privateValue){
return privateValue;
},
set: function(privateValue, newValue){
return newValue; // privateValue is set to whatever `set` returns
}
}
})
myObj.def({
myPrivate: {
get: function(privateValue){
return privateValue.somePublicProperty;
},
set: function(privateValue, newValue){
if (newValue.secreyKey === privateValue.unlockKey)
return newValue.newPublicProperty;
} else {
return privateValue.somePublicProperty;
}
}
}
})
Use the named parameters of a function to match arguments to what they should be named.
function RGB(red, green, blue){
return define({}, RGB, arguments);
}
var red = RGB(255, 0, 0);
// ->
{ red: 255,
green: 0,
blue: 0 }
function RGB(r, g, b){
this.define(arguments);
}
RGB.prototype = def.attach({}).define({
constructor: RGB,
toHex: someToHexFunction
});
var fuschia = new RGB(255, 0, 255);
// ->
{ r: 255,
g: 0,
b: 255 }