簡體   English   中英

如何避免JavaScript中函數輸出的多個變量重新聲明

[英]How to avoid multiple variable re-declarations on function outputs in JavaScript

請考慮以下示例

function doSomethingToAVariable(variable){
    return variable + 1
}

function doSomethingToAVariableASecondTime(variable){
    return variable + 2
}

function doSomethingToAVariableLastly(variable){
    return variable + 3
}

var myVariable = 0;
myVariable = doSomethingToAVariable(myVariable);
myVariable = doSomethingToAVariableASecondTime(myVariable);
myVariable = doSomethingToAVariableLastly(myVariable);

console.log(myVariable); // 6

我如何避免令人討厭的myVariable重新聲明? 可以將每個函數包裝到Promise鏈中作為解決方案嗎?

功能組成對救援。
看一下函數式編程庫,比如Ramda或lodash-fp。

這里有一個簡單的JS片段來組成函數:

//the compose-method you find in your regular FP-libs
var compose = (...funcs) => (value) => funcs.reduceRight((v,fn)=>fn(v), value);
//or a function wich takes the functions in opposite order, 
//wich might be more common to you
var pipe = (...funcs) => (value) => funcs.reduce((v,fn)=>fn(v), value);

compose是您嘗試構建的組合的直接映射

var composition = (value) => a(b(c(value)));
var composition = compose(a, b, c);
//it calls the functions from right to left

管道更傾向於您已知的命令式樣式,以逐步處理值

var composition = function(value){
    value = c(value);
    value = b(value);
    value = a(value);
    return value;
}
//pipe the value through c, then through b, then through a
var fn = pipe(c, b, a);
//wich in the end does exactly the same as the code built by compose

所以回到你的代碼:

var composition = pipe(
    doSomethingToAVariable,
    doSomethingToAVariableASecondTime,
    doSomethingToAVariableLastly
);
//or
var composition = compose(
    doSomethingToAVariableLastly,
    doSomethingToAVariableASecondTime,
    doSomethingToAVariable
);

//and run it
var myVariable = composition(0);

如果你想鏈接,那么你需要返回包含最終值的對象

function variableOperations( initialValue )
{
  this.value = initialValue;
  this.someOp1 = function(){ this.value += 1; return this; } 
  this.someOp2 = function(){ this.value += 2; return this; } 
}

var a = new variableOperations(1); //new object
a.someOp1().someOp2();

alert(a.value); //alerts 4

在這種情況下,您正在尋找所謂的“功能組合”:

var myVariable = doSomethingToAVariableLastly(doSomethingToAVariableASecondTime(doSomethingToAVariable(0)));

但是這些長函數名稱顯然無法讀取。

Promise通常僅對異步操作有用,雖然它們在這種情況下工作,但結果效率低下並且會引入異步依賴項,而不需要它們:

var promise = doSomethingToAVariable(0);
        .then(doSomethingToAVariableASecondTime);
        .then(doSomethingToAVariableLastly);

因為你只能從.then回調鏈的末尾訪問最終結果:

promise.then(function(myVariable) {
    // myVariable is now 6, and in scope
}

// but it's not in scope or usable here

為什么不看看Ramda的功能方法呢?

R.compose(
  doSomethingToAVariableLastly,
  doSomethingToAVariableASecondTime,  
  doSomethingToAVariable
)(myVariable)

以我的拙見,你的代碼非常好。

但是,如果你真的想要“鏈接”這些電話,你可以做這樣的事情。 但效率稍低。

 function chainCalls(initVal, funcs){ return funcs.reduce(function(val, f){ return f(val); }, initVal || 0); } function doSomethingToAVariable(variable){ return variable + 1 } function doSomethingToAVariableASecondTime(variable){ return variable + 2 } function doSomethingToAVariableLastly(variable){ return variable + 3 } var myVariable = chainCalls(0, [doSomethingToAVariable, doSomethingToAVariableASecondTime, doSomethingToAVariableLastly]); document.write(myVariable); 

另一種方法是創建一個像這樣的可重用功能鏈。

 function functionChain(){ var funcs = arguments; return function(value){ return Array.prototype.reduce.call(funcs, function(value, f){ return f(value); }, value); }; } function doSomethingToAVariable(variable){ return variable + 1 } function doSomethingToAVariableASecondTime(variable){ return variable + 2 } function doSomethingToAVariableLastly(variable){ return variable + 3 } var myVariable = functionChain( doSomethingToAVariable, doSomethingToAVariableASecondTime, doSomethingToAVariableLastly )(0); document.write(myVariable); 

如果只是將一些東西放在一起就像遞歸方法一樣簡單。 有點像使用promises但沒有實際使用它們。

function add(x) {
  return {
    done: () => x,
    add: (y) => add(x + y)
  }
}

let myVariable = 0;
add(myVariable).add(1).add(2).add(3).done(); // 6

DEMO

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM