2016-02-12 38 views
1

我知道一些通用記憶方法依賴於將參數列表串化並將其用作關鍵字。例如。如:Javascript中的通用記憶方法

Function.prototype.memoized = function() { 
    this._values = this.values || {}; 
    var fn = this; 
    return function() { 
     var key = JSON.stringify(Array.prototype.slice.call(arguments)); 
     if (fn._values[key]===undefined) { 
      fn._values[key]=fn.apply(this, arguments); 
     } 
     return fn._values[key]; 
    }; 
}; 

當一個人試圖memoize的一個「成員函數」,因爲一個人必須要還的JSON字符串化的背景下爲好,即把它當作一個隱式傳遞參數,這顯然會失敗。但是,如果上下文是全局對象或者同等深度的東西,或者以與函數本身無關的各種方式進行更改,那麼這種方法就不會奏效。

但即使我們堅持非「成員函數」,它可能並不總是可能完成strigify傳遞的參數列表,對吧?

三個問題:

  1. 做我理解正確的話,在一個通用的方法memoizing成員函數是無意義的?
  2. 我是否正確地理解,以通用方式記憶甚至非成員函數也是不可能的,因爲無法/不切實際地將任何可想象的參數列表完全串化?
  3. 如果2成立,那麼爲什麼很多書籍和博客都試圖在Function.prototype中定義一個通用的memoize函數?重點是什麼?
+0

你是什麼意思「stringify the context」?如果你的意思是對象的狀態,那麼它是非感性的。記事特別針對論點。 –

+2

至於你的第二點,確實不是所有可能的值都可以正確字符串化,但大多數值都可以。但是,memoization通過爲一組參數創建唯一標識符來工作。字符串化是一個常用的方法,但只要你可以創建一個唯一的標識符,你可以記住它。 –

回答

1

方法與this功能作爲副作用的來源。正如你可能知道有副作用的函數不能被記憶一樣,因爲這些效果不依賴於memoization依賴的方法的參數列表。

但是當然有一個解決方法。代替整個對象序列化(通過this引用),我們可以手動指定這些屬性,其中所述方法依賴:

function memoize(f, deps) { 
    let cache = {}; 

    return function(...args) { 
    let key = JSON.stringify([deps(), args]), v; 
    return cache[key] || (v = f.apply(this, args), cache[key] = v, v); 
    }; 
} 

function Person(firstName, lastName) { 
    this.firstName = firstName; 
    this.lastName = lastName; 

    this.fullName = memoize(
    function(title) { // memoized function 
     console.log('memoizing...'); 
     return title + ' ' + this.firstName + ' ' + this.lastName; 
    }, 
    function() { // dependencies 
     return [this.firstName, this.lastName]; 
    }.bind(this)); 
} 

let person = new Person('Jane', 'Doe'); 

// initial call 
console.log(person.fullName('Ms.')); // memoizing...Ms. Jane Doe 

// successive call 
console.log(person.fullName('Ms.')); // Ms. Jane Doe 

這僅僅是概念,而不是一個完全優化和測試溶液的證明。所有歸功於In Lehman's Terms


您的問題:

  1. 如果一個方法是關於它的計算非常昂貴,因此證明了努力,這需要其暗指的依賴的手工定義(由this ),那麼不,它可能是有用的
  2. 是的,有時這是不可能的,但爲什麼完全放棄幾乎通用的解決方案?
  3. 不知道!旅鼠? :D