11

What is the equivalent for Pythons functools.partial in Javascript or jQuery ?

1
  • Great question thank you. Commented Jul 25, 2019 at 19:32

4 Answers 4

7

ES6 solution

Here is a simple solution that works for ES6. However, since javascript doesn't support named arguments, you won't be able to skip arguments when creating a partial.

const partial = (func, ...args) => (...rest) => func(...args, ...rest);

Example

const greet = (greeting, person) => `${greeting}, ${person}!`;
const greet_hello = partial(greet, "Hello");

>>> greet_hello("Universe");
"Hello, Universe!"
Sign up to request clarification or add additional context in comments.

3 Comments

I'm new to python and when i first heard about partial the first thing that came to mind was bind, after seeing this answer it basically looks like bind, greet.bind(null, 'Hello') , please correct me if i'm wrong but this achieves the same goal as the partial function solution you have provided, with the same restriction to not being able to skip arguments and an additional ugly null argument for the this arg.
@Kostyantin2216 Seems like you are right, but can't confirm
MDN explicitly makes a reference to partial functions using bind: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
6

Something like this perhaps. It is a little bit tricky as javascript doesn't have named arguments like python, but this function comes pretty close.

function partial() {
  var args = Array.prototype.slice.call(arguments);
  var fn = args.shift();
  return function() {
    var nextArgs = Array.prototype.slice.call(arguments);
    // replace null values with new arguments
    args.forEach(function(val, i) {
      if (val === null && nextArgs.length) {
        args[i] = nextArgs.shift();
      }
    });
    // if we have more supplied arguments than null values
    // then append to argument list
    if (nextArgs.length) {
      nextArgs.forEach(function(val) {
        args.push(val);
      });
    }
    return fn.apply(fn, args);
  }
}

// set null where you want to supply your own arguments
var hex2int = partial(parseInt, null, 16);
document.write('<pre>');
document.write('hex2int("ff") = ' + hex2int("ff") + '\n');
document.write('parseInt("ff", 16) = ' + parseInt("ff", 16));
document.write('</pre>');

1 Comment

Btw I also found github.com/azer/functools which has an implementation.
2

To have the ES6 Solution also support classes:

const isClass = function (v) {
  // https://stackoverflow.com/a/30760236/2314626
  return typeof v === "function" && /^\s*class\s+/.test(v.toString());
};

const partial = (func, ...args) => {
  return (...rest) => {
    if (isClass(func)) {
      return new func(...args, ...rest);
    }
    return func(...args, ...rest);
  };
};

To use:

class Test {
  constructor(a, b, c) {
    this.a = a;
    this.b = b;
    this.c = c;
  }
}

const partialClass = partial(Test, "a");
const instance = partialClass(2, 3);
console.log(instance);

output:

➔ node tests/test-partial.js
Test { a: 'a', b: 2, c: 3 }

Comments

2

Here's an example using lodash:

const _ = require("lodash");

const greet = (greeting, person) => `${greeting}, ${person}!`;
const greet_hello = _.partial(greet, "Hello");

> greet_hello('John')
'Hello, John!'

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.