Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wrapping functions and function.length

Let's consider I have the following code

/*...*/
var _fun = fun;
fun = function() {
  /*...*/
  _fun.apply(this, arguments);
}

I have just lost the .length data on _fun because I tried to wrap it with some interception logic.

The following doesn't work

var f = function(a,b) { };
console.log(f.length); // 2
f.length = 4;
console.log(f.length); // 2

The annotated ES5.1 specification states that .length is defined as follows

Object.defineProperty(fun, "length", {
  value: /*...*/,
  writable: false,
  configurable: false,
  enumerable: false
}

Given that the logic inside fun requires .length to be accurate, how can I intercept and overwrite this function without destroying the .length data?

I have a feeling I will need to use eval and the dodgy Function.prototype.toString to construct a new string with the same number of arguments. I want to avoid this.

like image 472
Raynos Avatar asked Sep 06 '11 20:09

Raynos


People also ask

What is wrapping a function?

A wrapper function is a subroutine (another word for a function) in a software library or a computer program whose main purpose is to call a second subroutine or a system call with little or no additional computation.

What can be used to wrap a function with another function?

wrap() is used to wrap a function inside other function. It means that the first calling function (a function which is calling another function in its body) is called and then the called function is being executed. If the calling function does not call the called function then the second function will not be executed.

What is a wrapper function in R?

As the name implies, a wrapper function is just a function which wraps another function. Maybe inside it does something like set some default values for parameters, etc.

What is wrapping in JS?

In programming languages such as JavaScript, a wrapper is a function that is intended to call one or more other functions, sometimes purely for convenience, and sometimes adapting them to do a slightly different task in the process. For example, SDK Libraries for AWS are examples of wrappers.


1 Answers

I know you'd prefer some other way, but all I can think of is to hack together something with the Function constructor. Messy, to say the least, but it seems to work:

var replaceFn = (function(){
    var args = 'abcdefghijklmnopqrstuvwxyz'.split('');
    return function replaceFn(oldFn, newFn) {
        var argSig = args.slice(0, oldFn.length).join(',');
        return Function(
            'argSig, newFn',
            'return function('
                + argSig +
            '){return newFn.apply(this, arguments)}'
        )(argSig, newFn);
    };
}());

// Usage:
var _fun = fun;

fun = replaceFn(fun, function() {
  /* ... */
  _fun.apply(this, arguments);
});
like image 90
James Avatar answered Sep 28 '22 03:09

James