问题描述
我的理解是,按照规范,在bind()
中设置的参数是最终的,不能被覆盖。
我想知道是否有任何方式可以实现这样的目标,但是却无法给我想要的结果:
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));
显然,这失败了,因为函数上下文在进行currying时是硬编码的。
现在我可以清楚地进行黑客攻击了,
askThemX10 = function(){
return Student.times.bind(this,10);
}
askThemXTen = function(i){
return Student.times.call(this,10,i);
}
然后像这样使用它们:
console.log(askThemX10.bind(student1)()(5));
console.log(askThemXTen.bind(student1)(5));
或者我可以在Student
等中定义curried函数,等等。但是我想知道是否有更好的方法可以做到这一点。
解决方法
谈到现代JS。如果您可以转换代码并且不害怕使用实验性语法,则可以使用部分应用程序语法来实现所需的功能。虽然不建议用于生产:)
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));
,
每当您考虑使用bind
时,您都可能在做错事。在这种情况下,请使用普通的类:
class Student {
constructor(name) {
this.name = name;
}
multiply(i,j) {
return `I am: ${this.name} & think answer is: ${i*j}`;
}
}
然后创建学生实例:
const students = [
new Student("alice"),new Student("bob"),...
]
然后使“ ... times 10”函数全局起作用:
function askStudentX10(student,i) {
return student.multiply(i,10);
}
或者,如果您想保持美观和命名空间,请在Student
类上使其成为静态函数:
class Student {
static askStudentX10(student,i) {
return student.multiply(i,10);
}
constructor(name) {
...
}
...
}
简洁明了的代码,不需要bind
,没有潜在的与绑定相关的错误。简而言之,很明显。