Last active
December 17, 2015 17:59
-
-
Save XoseLluis/5649499 to your computer and use it in GitHub Desktop.
Enabling a simple form of Named Parameters in JavaScript
A function that receives another function and returns a new function where Named Parameters have been enabled. It has been updated so that a function accepts both unnamed and named parameters. Notice the Named parameters must be passed as the last ones.
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
//gets an array with the names of the parameters to a function | |
//taken from: | |
//http://stackoverflow.com/questions/9091838/get-function-parameter-names-for-interface-purposes/9092085#9092085 | |
function getFnParamNames(fn){ | |
var fstr = fn.toString(); | |
return fstr.match(/\(.*?\)/)[0].replace(/[()]/gi,'').replace(/\s/gi,'').split(','); | |
} | |
//used to mark as such the support objects used to pass named parameters | |
function NamedParameters(obj){ | |
obj._isNamedParams = true; | |
return obj; | |
} | |
//returns a new function that enables a form of Named Parameters in the function passed as parameter | |
//based on how named parameters work in C#, we can pass a mix of named and unnamed parameters, but the Named ones must be passed over as the last ones | |
function enableNamedParameters(fn){ | |
if(typeof fn != "function") | |
throw new Error("fn is not a function"); | |
if(fn._isNamedParamsEnabled || fn.length === 0){ | |
console.log(fn.name + " is already NamedParamsEnabled"); | |
return fn; | |
} | |
var paramNames = getFnParamNames(fn); | |
var namedParamsEnabledFn = function(){ | |
var params = []; | |
//traverse the parameters that we've received, cheking if it's a normal one or a NamedParameter object. if present, the NamedParameter should be the last parameter provided, so other parameters after it are ignored | |
for(var i=0; i<arguments.length; i++){ | |
if(!(arguments[i]._isNamedParams)){ | |
params.push(arguments[i]); | |
} | |
else{ | |
var paramsObj = arguments[i]; | |
for(;i<paramNames.length;i++){ | |
params.push(paramsObj[paramNames[i]]); | |
} | |
break; | |
} | |
} | |
return fn.apply(this, params); | |
}; | |
namedParamsEnabledFn._isNamedParamsEnabled = true; //metadata to avoid further applying of enableNamedParams | |
return namedParamsEnabledFn; | |
} | |
if (typeof module !== "undefined" && module.exports){ | |
exports.enableNamedParameters = enableNamedParameters; | |
exports.NamedParameters = NamedParameters; | |
} |
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 np = require("./namedParameters2"); | |
var enableNamedParameters = np.enableNamedParameters; | |
var NamedParameters = np.NamedParameters; | |
function sayHi(name, age, city, language){ | |
console.log("hi, my name is: " + name | |
+ " my age is: " + age | |
+ " I live in: " + city | |
+ " and my native language is: " + language); | |
} | |
var sayHi2 = enableNamedParameters(sayHi); | |
console.log("\n- using named parameters: "); | |
sayHi2(NamedParameters({ | |
city: "Prague", | |
age: 20, | |
name: "Iyan" | |
} | |
)); | |
console.log("\n- using unnamed parameters: "); | |
sayHi2("Iyan", 20, "Prague", "English"); | |
sayHi2("Iyan"); | |
console.log("\n- using both unnamed and named parameters:"); | |
sayHi2("Iyan", NamedParameters({ | |
language: "English", | |
age: 20, | |
city: "Prague" | |
})); | |
//notice the unnamed parameter "Prague" is being passed after the named ones, so it's being ignored | |
sayHi2("Iyan", NamedParameters({ | |
language: "English", | |
age: 20}), | |
"Prague" | |
); | |
//try to enable named params in a function where it's already enabled | |
var sayHi3 = enableNamedParameters(sayHi2); | |
console.log("just the same function was returned? " + (sayHi3 === sayHi2)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment