如何在没有闭包的情况下对共享状态进行编程
How do I program a shared state without closures?
var state = 0;
var interval = setInterval(function() {
// Do something depending on state
}, 1000)
由于一切都可以在没有闭包的情况下完成,这更像是一种智力练习,因为我看不到如何在没有闭包的情况下编写这样的东西。我是否通过引用将状态传递到匿名函数中?(JavaScript 不支持通过引用传递(
这是一个没有赢的答案,因为当你深入到它时,绝对没有不创建闭包的范围; 这是一个是否使用闭包以及如何使用它的问题。
闭包只是一个内部作用域,它保持对外部作用域的引用。
这样说吧:
/* global */
window.incr_id = 0;
window.tick = 0;
function nextTick () { window.tick += 1; }
window.incr_id = window.setInterval(nextTick, 1000);
这对你来说算不算结束?
从技术上讲,全局作用域相当于在其他语言的Main ()
内运行,因此nextTick
函数包含对外部作用域值(window
(的引用,导致在值表链上遍历,从而形成"闭包"。
你可以尝试类似的东西
function nextTick () { nextTick.value += 1; }
nextTick.value = 0;
。但是,鉴于自我参考来自大括号之外,因此属于更高的范围,这算不算?
function nextTick () { arguments.callee.value += 1; }
nextTick.value = 0;
当然,这将因此阻止您在严格模式下使用此解决方案(如果您希望安全,则应使用(。
当然,你可以创建一个闭包,这不是有问题的函数,而是创建monads,这样你就可以通过组合函数增量地传递值,而不是依赖闭包引用......
当然,问题在于setInterval
需要一个函数。
因此,无论你返回到哪个函数setInterval
,最终函数都必须使用闭包引用,不管你是否所有的应用函数都这样做了。
如果你引用一个在当前函数范围内没有定义的函数,或者我们只是在谈论标量,函数引用算作闭包引用吗?
故事的寓意:
window.value = 1;
window.obj.value = 1;
func.value = 0;
function func () { func.value = 1; }
function func () { arguments.callee.value = 1; }
如果你愿意承认"窗口"可以被引用为不是闭包(提示,它不能(,那么前两个是有效的。
如果您愿意接受在非严格模式下运行对您的客户、受众以及您的整体健康和福祉不利,那么最后一个可能是有效的。
您可以在没有闭包的情况下做任何事情。例如,状态可以存储在一个对象中,用指定的方法来"调用函数"。但是,您将需要一个不同的setInterval()
函数来采用您的方法类型,而不是现在采用的函数类型。
在 JavaScript 中,你不需要通过引用传递变量。通过在闭包中不使用var
,可以影响更高级别的var
。
简单的例子:
var state = 0;
var interval = setInterval(function(){
state++; // state increases by one every second
}, 1000);
// should console.log(4)
setTimeout(function(){console.log(state)}, 4500);
如果您这样做:
var state = 0;
var interval = setInterval(function(){
var state = 0;
state++; // state increases by one every second
// state is 1 every time at this point
// state outside closure is not affected
}, 1000);
// should console.log(0) - state refers to outside of closure
setTimeout(function(){console.log(state)}, 4500);
从某种意义上说,你可以认为 JavaScript 中的每个变量都是通过引用传递的,甚至没有将它们作为参数传递。事实上,如果您确实使用变量名称作为参数,它将在您要传递给的函数中重新定义,从而不会影响更高级别的变量。
向匿名函数传递参数,可能会也可能不会执行任何操作,具体取决于情况。在setInterval()
的情况下,不会将任何内容传递给您传递给它的函数。注意:
var state = 0;
var interval = setInterval(function(arg){
var state = 0;
state++; // state increases by one every second
// state is 1 every time at this point
// state outside closure is not affected
}, 1000);
与
var state = 0;
function what(arg){
var state = 0;
state++; // state increases by one every second
// state is 1 every time at this point
// state outside closure is not affected
}
var interval = setInterval(what, 1000);
因此,实际上该函数是在没有任何参数的情况下传递到setInterval()
的。你放入function what(){}
的任何参数都必须由setInterval()
传递一个参数,而则不传递这样的参数。
看看这个:
function whatever(func){
// takes function argument like `setInterval()`
// need to pass it something to have func take an argument
func("We'll just pass our function this String");
}
whatever(console.log); // now console.log() is passed an argument
因此,您可以看到,将函数作为参数的函数决定了作为参数传递的函数传递哪些参数。
我是否通过引用将状态传递到匿名函数中?
是的。尽管没有"关闭"setInterval
非常复杂,因为它实际上不允许你传递任何东西。
JavaScript 不支持通过引用传递
是的。我们不会使用对变量的引用,而是使用一个对象来存储状态。您将修改传递的对象,而不是修改闭包变量。
var state = {
value: 0
};
state.interval = setInterval(function() {
// Do something depending on this.value
}.bind(state), 1000);
- 在Knockoutjs中的ViewModels之间共享变量状态
- new Datamap() 在调用之间保持内存的共享状态
- 在角度上不同控制器之间共享状态
- 如何通过React Native中的组件共享登录状态
- JavaScript-使用sessionStorage保存文档之间共享的复选框状态
- 正在加载ui路由器状态下的共享模型
- Ember JS中控制器之间共享状态的正确方式
- 如果我两次使用相同的反应/冗余组件,它们会共享状态吗?
- 使用工厂时控制器/模板不共享相同的状态
- 摩卡测试共享状态,因为范围不好
- ui路由器——具有一条路由'的URL与另一个具有$stateParams的状态共享同一级别
- 更新React组件共享状态
- 如何在没有闭包的情况下对共享状态进行编程
- 在ui路由器中的状态之间共享ng模型数据
- 在控制器之间共享非单例状态(Angular Architecture)
- 在子组件之间共享父组件状态'州
- 保存公用共享的值状态(添加到URL)
- 如何在angularjs中使用两个不同的ui路由器在状态之间共享作用域数据?
- 使用服务在控制器之间共享状态
- 使用AngularJS进行SPA设计——在一些页面上共享状态,但不是所有页面