0

Is it possible to reference methods using function calls?

I thought I could try something like this:

function map(f,lst) {
// calling map method directly is fine.
    return lst.map(f)
}

function mapm(m,lst) {
// where m is a passed method
    return map( function(x) { return x.m() }, lst)
}

var list_a = [ [1,9],[2,8],[3,7],[4,6] ]
var list_b = mapm(pop,list_a)

>Uncaught ReferenceError: pop is not defined 
1
  • What is pop here? It's not defined anywhere in your code Commented Dec 18, 2012 at 1:05

2 Answers 2

4

Try:

mapm( 'pop', list_a )
...
return x[ m ]();

If you really want to reference the function itself:

mapm( list_a.pop, list_a ); // or Array.prototype.pop
...
return m.apply( x );
Sign up to request clarification or add additional context in comments.

Comments

1

You can use Function.prototype.call.bind to create a functional version of a method. This is referred to as "uncurrying this".

function map(f, lst) {
// calling map method directly is fine.
    return lst.map(f)
}

function mapm(m,lst) {
// where m is a passed method
    return map( function(x) { return m(x) }, lst)
}

var pop = Function.prototype.call.bind(Array.prototype.pop);

var list_a = [ [1,9],[2,8],[3,7],[4,6] ]
var list_b = mapm(pop, list_a)

If you need it to work in ancient browsers, you'll need to shim in bind:

if (!Function.prototype.bind) {
  Function.prototype.bind = function (oThis) {
    if (typeof this !== "function") {
      // closest thing possible to the ECMAScript 5 internal IsCallable function
      throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
    }

    var aArgs = Array.prototype.slice.call(arguments, 1), 
        fToBind = this, 
        fNOP = function () {},
        fBound = function () {
          return fToBind.apply(this instanceof fNOP && oThis
                                 ? this
                                 : oThis,
                               aArgs.concat(Array.prototype.slice.call(arguments)));
        };

    fNOP.prototype = this.prototype;
    fBound.prototype = new fNOP();

    return fBound;
  };
}

3 Comments

bind isn't safe to use without declaring it
Sure it is, if you're in an ES5 environment -- in other words, any browser made since 2010. Not everyone has to support IE8.
but enough people do that you shouldn't throw out solutions without a "this doesn't work in IE8" disclaimer

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.