# saveCallHistory(f)

[JS](https://lochiwei.gitbook.io/web/js) ⟩ [technique](https://lochiwei.gitbook.io/web/js/tech) ⟩ [decorator](https://lochiwei.gitbook.io/web/js/val/func/kind/higher/decorator) ⟩ :floppy\_disk: saveCallHistory(f)

{% hint style="success" %}
([](https://lochiwei.gitbook.io/web/js/val/func/kind/higher/decorator "mention")) <mark style="color:orange;">**make**</mark> a [..](https://lochiwei.gitbook.io/web/js/val/func "mention")/[method](https://lochiwei.gitbook.io/web/js/val/obj/method "mention") <mark style="color:yellow;">**save**</mark> its "<mark style="color:yellow;">**call history**</mark>" ([argument](https://lochiwei.gitbook.io/web/js/val/func/argument "mention")s).
{% endhint %}

{% tabs %}
{% tab title="💾 程式" %}

* replit：[saveCallHistory(f)](https://replit.com/@pegasusroe/decorator-saveCallHistoryf#saveCallHistory.js)

```javascript
// 📁 saveCallHistory.js
const {log} = console;

// throttle decorator
function saveCallHistory(f){

    // ⭐️ save call history (arguments) here
    let history = [];

    // 🔸 wrapper.history (getter)
    Object.defineProperty(wrapper, 'history', {
        get() { return history }
    })

    return wrapper;

    // ⭐️ decorated function
    function wrapper(...args){
        history.push(args);        // save arguments first
        return f.apply(this, args);
    }
    
}

// export
module.exports = { saveCallHistory }
```

{% endtab %}

{% tab title="💈範例" %}
replit：[saveCallHistory(f)](https://replit.com/@pegasusroe/decorator-saveCallHistoryf#saveCallHistory.js)

```javascript
// 📁 index.js
const { saveCallHistory } = require('./saveCallHistory.js');

// function
function f(...args) {
    return args.join();
}

// object
let user = {
    // method
    say(...args) { return args.join() }
};

// ⭐️ decorator: "saveCallHistory"
// ⭐️ make function/method save call history
f = saveCallHistory(f);
user.say = saveCallHistory(user.say);

// log
[
    f(1),
    f(1,2),

    f.history,           // [ [ 1 ], [ 1, 2 ] ]
    
    user.say(0),
    user.say(2, 3),
    user.say(4, 5, 6),
    
    user.say.history,    // [ [ 0 ], [ 2, 3 ], [ 4, 5, 6 ] ]

].forEach(x => console.log(x));
```

{% endtab %}

{% tab title="📗 參考" %}

* [x] JS.info ⟩ [Decorators and forwarding, call/apply](https://javascript.info/call-apply-decorators) ⭐️
* [ ] [ydkjs-scope-and-closures-v.2](https://lochiwei.gitbook.io/web/master/ref/book/you-dont-know-js-series-v.2/ydkjs-scope-and-closures-v.2 "mention") ⟩ Ch. 6  (by IIFE, ie. closure)
* [ ] [\[演算法\] Fibonacci：善用 cache 和 Memoization 提升程式效能](https://pjchender.blogspot.com/2017/09/fibonacci-cache-memoization.html) (by parameter)
* [ ] Wictionary ⟩  [memoize](https://en.wiktionary.org/wiki/memoize)&#x20;
  {% endtab %}

{% tab title="👥 相關" %}

* [](https://lochiwei.gitbook.io/web/js/val/func/kind/higher/decorator "mention")
  {% endtab %}
  {% endtabs %}
