试图理解 Javascript 箭头函数
Trying to understand Javascript arrow functions
所以我有一个我正在尝试扩展的开源库。
它具有以下值:
export const withX = fn => e => fn(getEvent(e).pageX);
export const getEvent = e => (e.touches ? e.touches[0] : e);
并且在 class 中,有原作者打算如何工作的实现:
...
onDragStart = withX(start => {
if (this.state.swiped) return;
this.setState({ start, pristine: false, moving: true });
});
我想改成这样(伪代码):
onDragStart() {
let startX = withX(return start);
}
但我不太确定该怎么做。
当我尝试这样的事情时:
let startX = withX();
或者这个:
let startX = withX(start => startX);
我得到的只是实际函数return。
任何人都可以向我解释箭头函数,让我明白这是怎么回事吗?这里有什么办法可以得到起始值吗?
其中一个被删除的答案有以下解决方案:
onDragStart(event) {
let startX = withX(_ => startX)(event);
console.log(startX);
}
不幸的是,这导致 undefined
箭头函数如下所示:
(arguments) => { function }
// OR
(arguments) => returnStatement
并翻译成
name(arguments) {
function
}
// OR
name(arguments) {
return returnStatement
}
唯一的区别是箭头函数没有名字。因此,在第一行,
export const withX = fn => e => fn(getEvent(e).pageX);
export const getEvent = e => (e.touches ? e.touches[0] : e);
等同于:
function withX(e) {
// As the comments state, I'm not sure why this is recursive...
return withX(getEvent(e).pageX);
}
function getEvent(e) {
return (e.touches ? e.touches[0] : e);
}
做你想做的你应该能够做的:
function onDragStart() {
let startX = withX(function(start) {
if (this.state.swiped) return;
this.setState({ start, pristine: false, moving: true });
});
}
箭头函数只是 shorthand 函数的语法糖。由于是 shorthand,它们也有一些小的限制,例如 this
绑定。
如果你正在为它们苦苦挣扎,首先要做的就是将箭头函数重新排列成它的正常函数形式,这样它可能更容易形象化。随着您使用它们的进步,这应该成为第二天性。
export const withX = fn => e => fn(getEvent(e).pageX);
export const getEvent = e => (e.touches ? e.touches[0] : e);
// Note here that the withX function is actually returning a function that
// is expecting to be called with e as the argument (e generally being an event)
function withX(fn){
return function(e){
return fn(getEvent(e).pageX);
};
}
// This function seems to return the first touch event (generally related to converting
// click events for mobile)
function getEvent(e){
if(e.touches) return e.touches[0];
return e;
}
既然您已经看到了这种转换,希望它对如何合并到您更熟悉的其他经典实现中更有意义。
比如你提供的demo中,
onDragStart = withX(start => {
if (this.state.swiped) return;
this.setState({ start, pristine: false, moving: true });
});
然后需要转换为
var onDragStart = withX(function(start){
if(this.state.swiped) return;
this.setState({ start, pristine: false, moving: true });
}.bind(this));
.bind(this)
在那里是因为在被发送的函数内部,将创建一个新的 this 绑定。但是,由于箭头函数不这样做(作为其语法糖的一部分),因此最初并不是必需的。
在这个代码转换中,应该也比较清楚start
是一个注入值,根据上面的翻译可以看出,start是被注入到回调函数中的pageX值。由于 start
在注入期间作用于内部函数,因此需要从内部作用域中提取它。
此外,如果您查看上面的翻译,您可以看到箭头函数的值 returned 是回调函数的值 returned。回调函数 fn 被注入起始值,因此,return从回调函数 fn 注入起始值将 return 在调用结束时的值。
方案一:直接return原实现中你想要的值
onDragStart = withX(start => {
if (this.state.swiped) return;
this.setState({ start, pristine: false, moving: true });
// instead of onDragStart being undefined, it will now hold the start variable
return start;
});
选项 2:在实现期间存储变量
var startX;
onDragStart = withX(start => {
if (this.state.swiped) return;
this.setState({ start, pristine: false, moving: true });
// now, assuming state.swiped was true, startX will hold the pageX value
// onDragStart will still end up being undefined in this implementation
startX = start;
});
选项 3:将这些版本之一转换为普通函数语法and/or使用不同的数据结构进行存储。
所以我有一个我正在尝试扩展的开源库。
它具有以下值:
export const withX = fn => e => fn(getEvent(e).pageX);
export const getEvent = e => (e.touches ? e.touches[0] : e);
并且在 class 中,有原作者打算如何工作的实现:
...
onDragStart = withX(start => {
if (this.state.swiped) return;
this.setState({ start, pristine: false, moving: true });
});
我想改成这样(伪代码):
onDragStart() {
let startX = withX(return start);
}
但我不太确定该怎么做。
当我尝试这样的事情时:
let startX = withX();
或者这个:
let startX = withX(start => startX);
我得到的只是实际函数return。
任何人都可以向我解释箭头函数,让我明白这是怎么回事吗?这里有什么办法可以得到起始值吗?
其中一个被删除的答案有以下解决方案:
onDragStart(event) {
let startX = withX(_ => startX)(event);
console.log(startX);
}
不幸的是,这导致 undefined
箭头函数如下所示:
(arguments) => { function }
// OR
(arguments) => returnStatement
并翻译成
name(arguments) {
function
}
// OR
name(arguments) {
return returnStatement
}
唯一的区别是箭头函数没有名字。因此,在第一行,
export const withX = fn => e => fn(getEvent(e).pageX);
export const getEvent = e => (e.touches ? e.touches[0] : e);
等同于:
function withX(e) {
// As the comments state, I'm not sure why this is recursive...
return withX(getEvent(e).pageX);
}
function getEvent(e) {
return (e.touches ? e.touches[0] : e);
}
做你想做的你应该能够做的:
function onDragStart() {
let startX = withX(function(start) {
if (this.state.swiped) return;
this.setState({ start, pristine: false, moving: true });
});
}
箭头函数只是 shorthand 函数的语法糖。由于是 shorthand,它们也有一些小的限制,例如 this
绑定。
如果你正在为它们苦苦挣扎,首先要做的就是将箭头函数重新排列成它的正常函数形式,这样它可能更容易形象化。随着您使用它们的进步,这应该成为第二天性。
export const withX = fn => e => fn(getEvent(e).pageX);
export const getEvent = e => (e.touches ? e.touches[0] : e);
// Note here that the withX function is actually returning a function that
// is expecting to be called with e as the argument (e generally being an event)
function withX(fn){
return function(e){
return fn(getEvent(e).pageX);
};
}
// This function seems to return the first touch event (generally related to converting
// click events for mobile)
function getEvent(e){
if(e.touches) return e.touches[0];
return e;
}
既然您已经看到了这种转换,希望它对如何合并到您更熟悉的其他经典实现中更有意义。
比如你提供的demo中,
onDragStart = withX(start => {
if (this.state.swiped) return;
this.setState({ start, pristine: false, moving: true });
});
然后需要转换为
var onDragStart = withX(function(start){
if(this.state.swiped) return;
this.setState({ start, pristine: false, moving: true });
}.bind(this));
.bind(this)
在那里是因为在被发送的函数内部,将创建一个新的 this 绑定。但是,由于箭头函数不这样做(作为其语法糖的一部分),因此最初并不是必需的。
在这个代码转换中,应该也比较清楚start
是一个注入值,根据上面的翻译可以看出,start是被注入到回调函数中的pageX值。由于 start
在注入期间作用于内部函数,因此需要从内部作用域中提取它。
此外,如果您查看上面的翻译,您可以看到箭头函数的值 returned 是回调函数的值 returned。回调函数 fn 被注入起始值,因此,return从回调函数 fn 注入起始值将 return 在调用结束时的值。
方案一:直接return原实现中你想要的值
onDragStart = withX(start => {
if (this.state.swiped) return;
this.setState({ start, pristine: false, moving: true });
// instead of onDragStart being undefined, it will now hold the start variable
return start;
});
选项 2:在实现期间存储变量
var startX;
onDragStart = withX(start => {
if (this.state.swiped) return;
this.setState({ start, pristine: false, moving: true });
// now, assuming state.swiped was true, startX will hold the pageX value
// onDragStart will still end up being undefined in this implementation
startX = start;
});
选项 3:将这些版本之一转换为普通函数语法and/or使用不同的数据结构进行存储。