试图理解 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使用不同的数据结构进行存储。