2016-05-18 15 views
0

Ich versuche, 'func.apply (this, func)' Wert zwischenzuspeichern, so dass es später nachgeschlagen werden kann, anstatt die Funktion erneut auszuführen. Das Problem ist, dass ich nicht weiß, wie oder was ich als Schlüssel verwenden soll.Javascript: Wie bekomme ich Schlüssel von function.apply()

Gibt es eine Möglichkeit, einen Schlüssel einer Funktion zuzuweisen, die später nachgeschlagen werden kann?

Code-Beispiel:

var m = function(func) { 
    var cached = {}; 
    return function() { 
    var key = ''; // how do I get or create the key of func.apply(this, func)? 

    if (cached[key]) { 
     return cached[key]; 
    } 

    cached[key] = func.apply(this, arguments); 
    return cached[key]; 
    }; 

}; 

Die m() Funktion sollte eine Funktion zurück, die, wenn sie aufgerufen wird, überprüft, ob sie bereits das Ergebnis für das gegebene Argument berechnet und zurück, dass Wert statt, wenn möglich.

+1

, was Sie 'Index bedeuten kann ' –

+1

So wie du es eingerichtet hast, jedes Mal wenn du es nennen würdest, würdest du den Cache wegblasen. – epascarello

+0

@ArunPJohny vielleicht frage ich nicht das Gleiche. Wie speichere ich func.apply (this, func) und schaue später nach? – nolabel

Antwort

1

Was suchen Sie nennt Memoization

See: Implementing Memoization in JavaScript

Hier sind ein Beispiel:

var myFunction = (function() { 
    'use strict'; 

    var functionMemoized = function() { 
    // set the argumensts list as a json key 
    var cacheKey = JSON.stringify(Array.prototype.slice.call(arguments)); 
    var result; 

    // checks whether the property was cached previously 
    // also: if (!(cacheKey in functionMemoized.cache)) 
    if (!functionMemoized.cache.hasOwnProperty(cacheKey)) { 
     // your expensive computation goes here 
     // to reference the paramaters passed, use arguments[n] 
     // eg.: result = arguments[0] * arguments[1]; 
     functionMemoized.cache[cacheKey] = result; 
    } 

    return functionMemoized.cache[cacheKey]; 
    }; 

    functionMemoized.cache = {}; 

    return functionMemoized; 
}()); 
+2

Ihre Implementierung hat einen Fehler. Wenn die Berechnung einen falschen Wert zurückgibt, wird immer die Berechnung ausgeführt. – epascarello

+0

Möchten Sie "Array.prototype.slice.call (Argumente)" erklären? – nolabel

+0

@epascarello: +1 du hast Recht, ich werde es ändern, um für 'undefined' zu testen, oder mit' hasOwnProperty' – jherax

-1

Wenn Sie den Wert der Funktion als String senden, können Sie das als Index mit einer kleinen Modifikation verwenden

var m = function(func, scope) { 

    return function() { 
    var cached = {}; 
    var index = func; // how do I get or create the index of func.apply(this, func)? 
    scope = scope || this; 
    if (!cached[index]) { 
     func = scope[func]; //Get the reference to the function through the name 
     cached[index] = func.apply(this, func);   
    } 

    return cached[index]; 
    }; 

}; 

Diese auf abhängt, wenn der Index existiert im this Objektverweis. Andernfalls sollten Sie einen anderen Bereich verwenden.

+0

Was ich im Sinn hatte, aber B. m (Funktion (a, b) {return a + b;}); – nolabel

+0

Wo definieren Sie die Funktion, die Sie anrufen möchten? Ist es global? – MiltoxBeyond

+1

Die Verwendung von 'func' als Suchschlüssel macht überhaupt keinen Sinn. – Bergi

1

Warum brauchen Sie ein Objekt mit einem Index? Speichern Sie einfach das Ergebnis/Schlüssel.

var m = function(func) { 
    var result=null; 
    return function() { 
     if (result===null) { 
      result = func.apply(this, arguments); 
     } 
     return result; 
    } 
}; 

Aber ich bin mir nicht sicher, dass das was du willst. Wenn die Funktion basierend auf Argumenten andere Werte zurückgibt, als Sie einen Schlüssel basierend auf den Argumenten verwenden möchten.

var m = function(func) { 
 
     var results = {}; 
 
     return function() { 
 
      var key = [].slice.call(arguments).join("-"); 
 
      if (results[key]===undefined) { 
 
       results[key] = func.apply(this, arguments); 
 
      } 
 
      return results[key]; 
 
     } 
 
    }; 
 

 

 
    var multiply = function (a,b) { 
 
     return a * b; 
 
    } 
 
    var mult = m(multiply); 
 
    console.log(mult(2,5)); //runs calculation 
 
    console.log(mult(2,5)); //uses cache

+0

Ich denke, die tatsächliche Frage ist, ob '[] .slice.call (Argumente) .join (" - ")' ist ein guter Index (Schlüssel) für Ihre Karte von gecachten Ergebnissen. – Bergi

+1

Per Index denke ich, er meint Schlüssel. Also seine Frage ist wirklich, was man als Schlüssel verwenden kann – slebetman

+0

@slebetman ja! Schlüssel! – nolabel

Verwandte Themen