View on GitHub


Bringing flexibility and clarity to JavaScript function calls.

Download this project as a .zip file Download this project as a tar.gz file

Quick start

Why? | Get | Loading

What is names.js?

names.js augments the function prototype. Features include:

How to use names.js

Step 1: Declare

var doSomething = Function.createNamed({
    args: [
        ['arg1', 'argumentType', 'defaultValue'],
        ['arg2', 'string', 'defaultValue'], // Eg.
        ['arg3', MyClass, someVar] // or this
    method: function(arg1, arg2, arg3) {

Step 2: Call

doSomething.applyNamed(null, {
    arg1: 42,
    arg2: 'something else',
    arg3: aVariable

A more detailed explanation

What problems does it solve? Why bother?

When you call a function, you provide a list of arguments whose purpose is opaque without going to the function definition and reading the argument names. Going with the adage that code is read far more frequently than it is written, it makes sense that it should be clear what role arguments to a function have without having to jump to the function itself. names.js solves that problem.

Which is clearer to understand?



node.clone.applyNamed(node, { deep: true });

This call to swfobject would be an ideal candidate for names.js!

swfobject.embedSWF("myContent.swf", "myContent", "300", "120", "9.0.0","expressInstall.swf", { foo: 'bar' }, { hello: 'world' }, { wmode: 'transparent' });

In addition to this, names.js supports:


You only need names.js (or the minified version, names.min.js) so you can do one of the following:

git submodule add path/to/clone/to


names.js can be loaded with requirejs but if you are not using that you can just include it in a script tag.


First set up a function by calling Function.create.

var myFunction = Function.create(
    [           // The items in this array represent the args of the function
                // They MUST be in the same order as they appear in the function
            'arg_name', // This is how the first argument will be identified when calling applyNamed
                        // It doesn't have to match the name used in the function but it makes sense to.
            'type',     // This can either be the type returned by typeof, a class function.
                        // If you don't want to type check this arg, just leave it out or set to null.
            'default_value' // If provided, this default value will be used when the arg is not provided.
        ... // repeat the array above for all args
    function(arg_name, ...) {


var divide = Function.create(
    function(dividend,divisor) {
        return dividend/divisor;

Optionally, you can add validation for any argument that needs it.

    arg_name: {
        test: /.*/, // This can be a regex or a function returning true or false
        required: true // If not set to true, if the arg is not provided it is not tested


    dividend: {
        required: true
    divisor: {
        test: function(arg) {
            if(arg === 0) {
                console.log('Cannot divide by 0');
                return false;
        required: true

Once set up, use Function.prototype.applyNamed to call your function. It works just like Function.prototype.apply (docs) except you pass an object as the second value instead of an array.


var quotient = divide.applyNamed(null, {
    dividsor: 5,
    dividend: 20

Further Usage Information

Omitting an argument sets it to null

var anyOldFunction = Function.createNamed({
    args: [['arg1'], ['arg2'], ['arg3']],
    method: function(arg1, arg2, arg3) {
        return [arg1, arg2, arg3];

anyOldFunction.applyNamed(null, {
    arg3: 'baz',
    arg2: 'foo'
}); // returns [null, 'foo', 'baz']

The __names property

Your function has a property __names. You shouldn't need to manually change this, but it's useful to know for debugging. Here is the structure:

myFunction.__names = {
    args: {
        ['arg1','arg2'] // The args in order
    types: {
        arg1: 'string',
        arg2: Class
    defaults: {
        arg1: 'default value'
        arg2: classInstance
    validation: {
        arg1: {
            test: /.*/,
            required: true
        arg2: {
            test: function() { return true; }

Quick usage

You can use applyNamed with any function, not just those created with createNamed. However, it is only recommended for test or prototype situations as it will not work once the code is minified.

// This
myFunc.applyNamed(null, {
    arg1: 'something',
    arg2: 'somethingElse'

// Works with this
function myFunc(arg1, arg2) {

// But not this (the same code minified)
function a(b,c){