我正在查看这段代码(Redux源代码中的createStore实现的简化版本)
function createStore(reducer) {
var state;
var listeners = []
function getState() {
return state
}
function subscribe(listener) {
listeners.push(listener)
return unsubscribe() {
var index = listeners.indexOf(listener)
listeners.splice(index, 1)
}
}
function dispatch(action) {
state = reducer(state, action)
listeners.forEach(listener => listener())
}
dispatch({})
return { dispatch, subscribe, getState }
}
我的问题仅针对下面的方框
function subscribe(listener)
return unsubscribe() {
var index = listeners.indexOf(listener)
listeners.splice(index, 1)
}
大括号中的部分
{
var index = listeners.indexOf(listener)
listeners.splice(index, 1)
}
该块是否传递给unsubscribe()方法?与Ruby的块有什么相似之处吗?在javascript中如何运作?
答案 0 :(得分:2)
如果您调用subscribe
并将其传递给侦听器,它将返回一个您可以在以后随时调用的函数。例如:
const {dispatch, subscribe, getState} = createStore(this.myReducer);
// for demonstration purpose. Now you have references to the values createStore() returns;
const subscription = this.subscribe(this.listener)
现在,只要您调用this.subscription()
,它将执行以下操作:
var index = listeners.indexOf(listener)
listeners.splice(index, 1)
listener
被保存在闭包中。
答案 1 :(得分:2)
首先,您发布的代码存在一些问题。精简的createStore()
函数版本是:
function createStore(reducer) {
var listeners = [];
function subscribe(listener) {
listeners.push(listener);
return function unsubscribe() {
var index = listeners.indexOf(listener)
listeners.splice(index, 1)
};
}
return {subscribe};
}
请注意,您忘记了一些分号,并且(编辑:OP没忘记什么。将skips semicolons to conform还原到React Router ESLint ){{1} }方法不是返回subscribe()
,而是返回function unsubscribe()
。
现在,回答问题this article是一个不错的演讲,以说明Ruby和JavaScript在此主题上的区别。
Ruby方法不是函数或一等公民,因为它们不能作为参数传递给其他方法,不能由其他方法返回或分配给变量。 Ruby proc是一流的,类似于JavaScript的一流功能。
在JavaScript中,函数是真正的一等公民。它们可以像其他任何数据一样传递。
在我们的示例中,unsubscribe()
函数返回一个对象,其中包含函数/方法createStore()
。通过返回函数名称(subscribe()
)来实现。同样,subscribe
也返回一个函数,但这一次该函数的声明直接在subscribe()
语句内部进行。两者都是传递函数的有效方法。
通过函数调用实例化return
时,将获得返回的对象。
createStore
新对象具有方法var myObject = createStore("foo");
。如果调用该方法,则将获得subscribe()
函数。
unsubscribe()
当然,您可以通过以下方式一行完成:
var myFunction = myObject.subscribe("bar");
在下面的代码段中尝试它:
var myFunction = createStore("foo").subscribe("bar");
您可能还想了解MDN中的对象。
答案 2 :(得分:1)
该代码块是订阅方法返回的unsubscribe
函数的一部分