2017-05-07 38 views
0

在下面的一段蹦床代码中,我将从我的视图中显示的按钮中调用 onclick = export(add,5)。如何确保此通话始终返回5的值,而不取消注释下面代码中//x=0的行?导出功能需要设置为纯函数

var x = 0; 

function repeat(operation, num) { 
    return function() { 
     if (num <= 0) { 
      console.log(x); 
      // x=0; 
      return; 
     } 
     operation(); 
     return repeat(operation, --num); 
    } 
} 

function trampoline(fn) { 
    while (fn && typeof fn === 'function') { 
     fn= fn(); 
    } 
} 

this.export = function (operation, num) { 
    trampoline(function() { 
     return repeat(operation, num); 
    }); 
} 

function add() 
{ 
    ++x; 
} 

基本上,我想一个解决方案,我的变量x的范围将确保程序总是返回时,执行n次相同的输出(换句话说,我要设置“出口”作为一个纯粹的功能)

回答

1

我不清楚你在问什么,但你没有理由依赖外部状态,突变或重新分配这个功能。 ++x--n是功能性编程幻想世界的噩梦 - 你会想要以几乎任何常见的模式避免它们。

// checking typeof === 'function' is not really reliable in functional programming 
 
// function return values are perfectly good return types 
 
// use data abstraction to mark tail calls 
 
const trampoline = { 
 
    bounce: (f, x) =>({ isBounce: true, f, x}), 
 
    run: t => { 
 
    while (t && t.isBounce) 
 
     t = t.f(t.x) 
 
    return t 
 
    } 
 
} 
 

 
// local binding, no mutation, just return x + 1 
 
const add = x => x + 1 
 

 
// bounced repeat 
 
const repeatAux = (f,n) => x => 
 
    n === 0 ? x : trampoline.bounce(repeatAux(f, n - 1), f(x)) 
 

 
// this is the function you export 
 
// it runs trampolined repeatAux with initial state of 0 
 
const repeat = (f,n) => 
 
    trampoline.run(repeatAux(f,n)(0)) 
 

 
// all calls to repeat are pure and do not require external state, mutation, or reassignment 
 
console.log(repeat(add, 5)) // 5 
 
console.log(repeat(add, 5)) // 5 
 
console.log(repeat(add, 7)) // 7 
 
console.log(repeat(add, 7)) // 7 
 

 
// repeat 1 million times to show trampoline works 
 
console.log(repeat(add, 1e6)) // 1000000


ES5,按要求

var trampoline = { 
 
    bounce: function (f, x) { 
 
    return ({ isBounce: true, f, x}) 
 
    }, 
 
    run: function (t) { 
 
    while (t && t.isBounce) 
 
     t = t.f(t.x) 
 
    return t 
 
    } 
 
} 
 

 
var add = function (x) { return x + 1 } 
 

 
var repeatAux = function (f,n) { 
 
    return function (x) { 
 
    return n === 0 
 
     ? x 
 
     : trampoline.bounce(repeatAux(f, n - 1), f(x)) 
 
    } 
 
} 
 

 
var repeat = function (f,n) { 
 
    return trampoline.run(repeatAux(f,n)(0)) 
 
} 
 

 
console.log(repeat(add, 5)) // 5 
 
console.log(repeat(add, 5)) // 5 
 
console.log(repeat(add, 7)) // 7 
 
console.log(repeat(add, 7)) // 7 
 
console.log(repeat(add, 1e6)) // 1000000

+0

感谢Naomik。这完全回答了我的问题。我正在寻找使这个函数纯粹没有明确地清除x。但是,您是否具有与该功能等效的ECMAScript 5?这将是很大的帮助。 – vamsee

+0

@vamsee,我加了es5 – naomik

+0

非常感谢Naomik。我是认真的 :) – vamsee