0

My understanding is that as per spec, the parameters set in bind() are final and cannot be overridden.

I would like to know if there is any way of achieving something like this, which fails to give me the results that I want:

const Student = {
    name: "",
    times: function(i, j) {
        return `I am: ${this.name} & think answer is: ${i*j}`;
    }
};

const student1 = {
    name: "student1"
}
const student2 = {
    name: "student2"
}

const askThemTimesBy10 = Student.times.bind(null, 10);

console.log(askThemTimesBy10.bind(student1)(5));
console.log(askThemTimesBy10.bind(student2)(5));

obviously this fails since the function-context is hard-coded at the time of currying.

Now I can clearly do hacks like:

askThemX10 = function(){
    return Student.times.bind(this, 10);
}

askThemXTen = function(i){
    return Student.times.call(this, 10, i);
}

and then use them like:

console.log(askThemX10.bind(student1)()(5));
console.log(askThemXTen.bind(student1)(5));

or I can define the curried function inside Student etc. etc. but I'd like to know if there is a nicer way of doing this.

Maths noob
  • 1,684
  • 20
  • 42

2 Answers2

1

Speaking of modern JS. If you can transpile your code and do not afraid to use experimental syntax, you may achieve what you want using partial application syntax. Not recommended for production though :)

Demo

const Student = {
    name: "",
    times(i, j) {
        return `I am: ${this.name} & think answer is: ${i*j}`;
    }
};

const student1 = {
    name: "student1"
}
const student2 = {
    name: "student2"
}

const askThemTimesBy10 = Student.times.call(?, 10, ?); // <--- pew pew 

console.log(askThemTimesBy10(student1, 5));
console.log(askThemTimesBy10(student2, 6));
Yury Tarabanko
  • 44,270
  • 9
  • 84
  • 98
-1

Any time you're thinking of using bind, you're probably doing something wrong. In this case, use a normal class:

class Student {
  constructor(name) {
    this.name = name;
  }

  multiply(i, j) {
    return `I am: ${this.name} & think answer is: ${i*j}`;
  }
}

and then create student instances:

const students = [
  new Student("alice"),
  new Student("bob"),
  ...
]

And then make that "... times 10" function either a global:

function askStudentX10(student, i) {
  return student.multiply(i, 10);
}

Or if you want to keep things nice and namespaced, make it a static function on the Student class:

class Student {
  static askStudentX10(student, i) {
    return student.multiply(i, 10);
  }

  constructor(name) {
    ...
  }

  ...
}

Nice and explicit code, no bind required, no potential bind-related bugs. Just plain, obvious, code.

Mike 'Pomax' Kamermans
  • 49,297
  • 16
  • 112
  • 153
  • I'd say anytime a class is used you're doing something wrong. – evolutionxbox Sep 29 '20 at 21:53
  • cool, but also fairly nonsense. `bind` and `apply` are legacy functions from when JS was much more low level than it is today (they're still there, because we made the conscious choice to never deprecate JS APIs, which is why we still have insane things like `document.write`), whereas modern class syntax is literally that. Use modern JS, not JS from twenty years ago. – Mike 'Pomax' Kamermans Sep 29 '20 at 21:53
  • ha i actually come from a functional BE background, so I quite like my binds and curries and all that. :) interesting to see divergent opinions on the subject. – Maths noob Sep 29 '20 at 21:55
  • 1
    Although I was joking, a tool is just a tool, `bind` is _still_ useful. Also, the "use modern JS" argument is a bad one. – evolutionxbox Sep 29 '20 at 21:55
  • it's _extremely_ useful, but in an extremely small number of cases, which is why if you're using `bind` in normal, modern JS, it's almost a given you shouldn't be using `bind`. Like in this case. If you're writing a transpiler in JS, different story, but there is nothing remarkable about the code in this question other than "this is an ancient way of writing JS code and you should really be learning and writing modern JS instead". – Mike 'Pomax' Kamermans Sep 29 '20 at 21:56
  • @Mike'Pomax'Kamermans as a side note, I wouldn't put `askStudentX10` as a static method. The Student class/object is supposed to resemble something generic whereas that function is local and specific, but that's besides the point :) – Maths noob Sep 29 '20 at 21:58