0

我的理解是,根据规范,设置的参数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));

显然这会失败,因为函数上下文在柯里化时是硬编码的。

现在我可以清楚地做一些黑客攻击,比如:

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等等,但我想知道是否有更好的方法来做到这一点。

4

2 回答 2

1

说到现代 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));
于 2020-09-29T22:12:31.190 回答
-1

每当您考虑使用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"),
  ...
]

然后将“...乘以 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不需要,没有潜在的绑定相关错误。简单明了的代码。

于 2020-09-29T21:49:57.703 回答