2017-06-10 17 views
0

我想用一個參數調用一個函數並存儲該值,以便下一次我不使用參數調用該函數時,它將使用設置的最後一個參數。這是可能的JavaScript?JavaScript - 調用之間函數中的持久數據?

編輯:這裏有更多的信息是什麼我想實現...

var track = 0; 
$.getJSON('songsMetadata.json', function(data){ 
    appendData(data); 
}); 
player.bind("ended", function(){ 
    track++ 
    appendData(); 
}); 
function appendData(data){ 
    /* Here I want to populate 
    the inside 'data' argument 
    only once (in the callback of 
    getJSON) and use that same 
    data in the 'player.bind' 
    callback */ 

    //Some code to append data[track] to an HTML list 
} 
+0

是啊,肯定是可以做到的,但如果你能告訴我有更多的信息,我可以給你寫一個例子。爭論會是什麼? –

+0

[Javascript:用狀態創建一個函數]的可能重複(https://stackoverflow.com/questions/8161671/javascript-creating-a-function-with-state) – Andreas

+0

你可能會感興趣[迭代器和生成器]( https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/Iterators_and_Generators) – BoltKey

回答

2

你需要保持在封閉範圍內的最後一個可以接受的參數的引用。例如:

var ref; 
 

 
function foo (arg) { 
 
    if (!arg) { // or arg === undefined if you want to be safe 
 
    arg = ref; 
 
    } else { 
 
    ref = arg; 
 
    } 
 

 
    // actual function behavior here 
 
    console.log(arg); 
 
} 
 

 
foo(); // undefined 
 
foo(2); // 2 
 
foo(); // 2 
 
foo(3); // 3 
 
foo(); // 3

如果你想重複這種行爲,你可能要考慮寫一個包裝函數緩存一個接受函數的參數。例如:

function cacheFn (fn) { 
 
    var ref; 
 
    
 
    return function (arg) { 
 
    if (!arg) { 
 
     arg = ref; 
 
    } else { 
 
     ref = arg; 
 
    } 
 
    
 
    return fn(arg); 
 
    } 
 
} 
 

 
function foo (arg) { 
 
    console.log(arg); 
 
} 
 

 
var cachedFoo = cacheFn(foo); 
 

 
cachedFoo(2); 
 
cachedFoo(); 
 
cachedFoo(3); 
 
cachedFoo();

+0

我對這段代碼有點困惑。你能解釋一下正在做什麼嗎?例如,當你返回一個函數時會發生什麼?爲什麼你將foo函數傳遞給cacheFn?我知道這段代碼有效,但我真的很感興趣,爲什麼 – medicengonzo

+1

@medicengonzo認爲'cachedFn'作爲一個附件,你可以對一個函數進行操作,以便它執行相同的功能,但帶來額外的好處。我們做的第一件事是聲明一個變量'ref',它將(內部)用於存儲傳遞給函數的最新參數。然後我們返回一個函數來封裝傳入的函數(在你的案例中爲'appendData')。這將最終運行你的函數,但首先我們做一些邏輯來確定已經通過了一個參數。如果是這樣,我們直接傳入這個參數並更新'ref',如果不是,我們傳遞'ref'。 – Damon

+1

這種模式的好處是你的函數,appendData或者你想要使用這個行爲的任何其他函數對整個過程都是「啞」。它只能關注自己需要完成的邏輯。 – Damon

1

在更普遍的方式:

function enclose(func){ 
var args=[]; 
return function(...passed){ 
    args=passed.length?passed:args; 
    func(...args); 
}; 
} 

Usecases:

var log=enclose(console.log.bind(console)); 
log(5,1); 
log(); 
+1

對於'n' args這也是一個更一般的soln,假設es6可用。如果不能用'arguments'和'apply'輕鬆地複製傳播行爲。 +1 – Damon

+0

@damon +1爲大致的想法;) –