Javascript 中的 Eta 转换
Eta-conversion in Javascript
Eta-conversion 正在考虑函数 (x) => f(x)
与函数 f
相同。在工作中重构代码时,我试图使用这种等价性来简化一些高阶函数调用。然而,事情并没有完全解决,我对实际发生的事情有些迷茫,在 Javascript 还很陌生。这是一个最小的例子,我希望它能正确地说明我的问题。
const station = {
take: (f) => f(5),
love: function(car) {
this.take((x) => car.addFuel(x));
},
hate: function(car) {
this.take(car.addFuel);
}
};
const mercedes = {
fuel: 0,
addFuel: function(amount) {
this.fuel += amount;
}
};
station.love(mercedes);
console.log(mercedes.fuel);
// output: 5
station.hate(mercedes);
console.log(mercedes.fuel);
// output: 5; expected output: 10
根据 eta 等价性,我希望 station
对象的 love
和 hate
函数表现相同。但是,似乎 hate
函数实际上什么也没做。这里发生了什么?
this
存在范围界定问题。在您的原始代码中 hate
回调 this
指的是全局 window
对象。您需要使用 Function.prototype.bind() 为 this
.
绑定正确的范围
const station = {
take: (f) => f(5),
love: function(car) {
this.take((x) => car.addFuel(x));
},
hate: function(car) {
this.take(car.addFuel.bind(car));
}
};
const mercedes = {
fuel: 0,
addFuel: function(amount) {
this.fuel += amount;
}
};
station.love(mercedes);
console.log(mercedes.fuel);
station.hate(mercedes);
console.log(mercedes.fuel);
Eta-conversion 正在考虑函数 (x) => f(x)
与函数 f
相同。在工作中重构代码时,我试图使用这种等价性来简化一些高阶函数调用。然而,事情并没有完全解决,我对实际发生的事情有些迷茫,在 Javascript 还很陌生。这是一个最小的例子,我希望它能正确地说明我的问题。
const station = {
take: (f) => f(5),
love: function(car) {
this.take((x) => car.addFuel(x));
},
hate: function(car) {
this.take(car.addFuel);
}
};
const mercedes = {
fuel: 0,
addFuel: function(amount) {
this.fuel += amount;
}
};
station.love(mercedes);
console.log(mercedes.fuel);
// output: 5
station.hate(mercedes);
console.log(mercedes.fuel);
// output: 5; expected output: 10
根据 eta 等价性,我希望 station
对象的 love
和 hate
函数表现相同。但是,似乎 hate
函数实际上什么也没做。这里发生了什么?
this
存在范围界定问题。在您的原始代码中 hate
回调 this
指的是全局 window
对象。您需要使用 Function.prototype.bind() 为 this
.
const station = {
take: (f) => f(5),
love: function(car) {
this.take((x) => car.addFuel(x));
},
hate: function(car) {
this.take(car.addFuel.bind(car));
}
};
const mercedes = {
fuel: 0,
addFuel: function(amount) {
this.fuel += amount;
}
};
station.love(mercedes);
console.log(mercedes.fuel);
station.hate(mercedes);
console.log(mercedes.fuel);