1

Or, in other words, how to make this work:

function foo(){}
//do something that modifies foo as if it was defined with "function foo(a,b,c){};"
console.log(foo.length); 
//output: 3
4
  • 1
    Function declarations don't end with a semi-colon. Commented Jun 11, 2012 at 23:52
  • Functions are immutable. Commented Jun 11, 2012 at 23:54
  • Does the function body use the arguments a, b, and c. If not, what's the point of defining them? If yes, why didn't it specify them in the first place? Commented Jun 11, 2012 at 23:55
  • Are you doing this in a browser, or Node.JS? Node's got a package for some fake inheritance that might help. Commented Jun 11, 2012 at 23:58

4 Answers 4

2

It is possible, but maybe not very nice:

function lengthDecorator(fun) {
    function update(len) {
        var args = []; // array of parameter names
        for (var i = 0; i < len; ++i) {
            args.push('a' + i);
        }

        var result = new Function('fun',
            'return function(' + args.join(',') + ') {' +
                'var args = Array.prototype.slice.call(arguments);' +
                'return fun.apply(this, args);' + // call supplied function
            '}'
        ); // create a function that will return a function

        result = result(fun); // make the fun param known to the inner function
        result.update = update;
        return result;
    }
    return update(fun.length);
}

Example usage:

var foo = lengthDecorator(function(a,b) {
    return a+b;
});

print('foo.length: ' + foo.length);
print('foo(2, 3): ' + foo(2, 3));

print('');
foo = foo.update(42);
print('foo.length: ' + foo.length);
print('foo(2, 3): ' + foo(2, 3));

Output:

foo.length: 2
foo(2, 3): 5

foo.length: 42
foo(2, 3): 5

(Live demo: Ideone.com, jsFiddle)

lengthDecorator wraps the supplied function with a function that takes the same amount of parameters as the supplied function. The parameter count can be changed with update.

C.f.

Sign up to request clarification or add additional context in comments.

Comments

1
function foo() {}
alert(foo.length); // 0

foo = function (a, b, c) {}
alert(foo.length); // 3

1 Comment

The question implies that the function body should not be replaced.
0

I'm not sure what you're actually trying to do, but you can store the old foo in var and then redefine foo.

function foo() {...}

var oldfoo = foo;
foo = function (a, b, c) {
    oldfoo();
}

But what's the point?

2 Comments

This won't work (because I don't know the length before running the code). I'm trying to write a decorator but I'm having trouble with the fact the function returned by it is reporting a wrong value for function.length
@Dokkat perhaps you could share more of your code? It's hard to know what exactly you're doing or why the foo.length value would matter at all.
-1

The length property of a function object is non-writable and non-configurable, so there is no way to change its value.

You could define a new function which invokes the original function internally...

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.