2016-10-04 152 views
1
// @flow 
import { compose, createStore } from 'redux'; 
import thunk from 'redux-thunk'; 

const composedStore = compose(
    applyMiddleware(thunk), 
    __CLIENT__ && window.devToolsExtension ? window.devToolsExtension() : f => f 
)(createStore) 

此代码是来自React-Redux'Universal'应用样板的文件。我可以在大部分时间把我的头围绕它,虽然在撰写函数的第二个参数中的错误的情况条件逻辑让我跳起来 - 什么是f => f ???这段代码做了什么?

除非我错了,这是香草JS相当于

function(f){ 
    return f; 
} 

在这种情况下,哪里是f说法来自何处,什么做此功能实际上回报?在文件的其他地方没有其他参考f变量。很混乱。

+0

哈哈...你钉了它的人。这是其他条件下的JS等价物。 –

+0

'f => f'是[身份函数](https://en.wikipedia.org/wiki/Identity_function)。 –

回答

1

除非我错了,这是香草JS相当于

function(f){ 
    return f; 
} 

的好看多了,因为函数体不使用thisarguments;有两点要注意:

  1. 箭头功能(f => f)关闭了thisarguments(而不是有其自己的含义它们),其中function表达不会,但由于功能的内容,它没关系,因为它不使用它们。

  2. 箭头函数香草JavaScript(截至ES2015)。

在这种情况下,其中的F参数来自何处?

它来自任何回调你传入一个函数的相同地方:不管怎样调用它。此回调被传递到compose,所以知道怎么回事被称为以怎样的参数(S),你看看compose定义终极版:

每个功能预计将接受一个单一的参数。它的返回值将作为站立在左边的函数的参数提供,等等。例外是可以接受多个参数的最右边的参数,因为它将提供最终组合函数的签名。

因此,该函数将接收任何返回的函数applyMiddleware(thunk)返回。

f => f函数的唯一原因是,作者可以使用单行;例如,它们需要一些用于假操作数的条件运算符。他们本来可以这样做:

let temp = applyMiddleware(thunk)(createStore); 
if (__CLIENT__ && window.devToolsExtension) { 
    temp = window.devToolsExtension()(temp); 
} 
const composedStore = temp; 

......但大概是想避免临时变量。

+0

这是我的一排中的第二个问题,你正在系统地分解成一个很好的答案。谢谢,我很欣赏它:)我认为它对于我来说是一个缺失的难题,因为它会为最终的组合函数提供签名。“异常是最右边的参数,它可以接受多个参数。你能否提供有关“最终组合函数”的签名是什么的见解? – styke

+1

@styke:与JavaScript函数最接近的“签名”是* arity *(声明参数的数量),它作为函数的'length'属性公开。所以'函数foo(a,b){}'有'foo.length'等于2; 'bar(){}''bar.length'等于0.我猜'compose'返回的函数的长度是从最右边的参数开始的。 –

0

我认为这就像noop。如果我们不在Dev Tools扩展中,compose的第二个参数是一个只返回给定值的函数。

const isDevToolExtension = __CLIENT__ && window.devToolsExtension; 
const returnItself = function(f) { 
    return f; 
} 

const composedStore = compose(
    applyMiddleware(thunk), 
    isDevToolExtension ? window.devToolsExtension() : returnItself 
)(createStore)