2016-05-26 7 views
1
zu implementieren

Ich habe viel über call() und bind() in JavaScript zu lesen, insbesondere die Erstellen shorcuts Abschnitt auf diesen MDN article.Versuch

Ich versuche, die folgende Python-artige Funktion in JS zu implementieren:

var arr = [1,2,3]; 
len(arr); // 3 

Ich weiß, das ist ein konstruiertes Beispiel ist, aber ich versuche, meinen Kopf um diese Methoden zu wickeln. Hier ist, wie ich es umgesetzt:

var len = Function.prototype.call.bind(Array.prototype.slice.length); 
len([1,2,3]); 

Wenn ich es laufen, erhalte ich:

len([1,2,344]) 
^ 

TypeError: len is not a function 
    at Object.<anonymous> (/private/var/folders/j6/3fs5_k3n17z_0j2xrwj6sphw0000gn/T/CodeRunner/Untitled 11.js:2:1) 
    at Module._compile (module.js:435:26) 
    at Object.Module._extensions..js (module.js:442:10) 
    at Module.load (module.js:356:32) 
    at Function.Module._load (module.js:311:12) 
    at Function.Module.runMain (module.js:467:10) 
    at startup (node.js:136:18) 
    at node.js:963:3 

Was ich hier fehlt, zu verstehen, wie das funktioniert?

Antwort

1

Wenn Sie die Variable len sind einstellen, in Ihrem Code, sind Sie tatsächlich len auf eine Kopie der Funktion Function.prototype.call mit einem this (Kontext) von Array.prototype.slice.length Einstellung.

Ich denke, Sie missverstehen die Verwendung von bind(). Sagen wir, ich habe eine Funktion len:

var len = function() { 
    return this.length; 
}; 

Und Sie wollten die Länge eines Arrays erhalten:

len.call([1,2,3]); 

In diesem Fall this in len ist das Array [1,2,3], weil wir call verwendet zu liefern this. Sagen wir, dass Array dauerhaft binden möchten diese Funktion und speichern sie in einer Variable, die wir jederzeit nutzen können:

var myArrayLen = len.bind([1,2,3]); 

Nun myArrayLen im Grunde eine Kopie len ist, permanent mit einem this von [1,2,3] gebunden. Wenn wir es nennen, gibt es 3.

In Ihrem Beispiel ist Array.prototype.slice.length tatsächlich die Länge der Funktion Array.prototype.slice, die der number of arguments that can be passed to the function entspricht.

Es gibt keine in der Länge() Funktion eingebaut ist, so dass Ihr (zugegebenermaßen) erfundenes Beispiel zu folgen, müssen wir nur noch eine Funktion machen, die die Länge bietet, fügen Sie ihn in dem Array-Prototyp, und binden Sie es Function.prototype.apply.bind(); mit:

Array.prototype.len = function() { return this.length; }; 
var len = Function.prototype.apply.bind(Array.prototype.len); 
len([1,2,3]); // 3 
+0

danke, aber dies ermöglicht nicht die Flexibilität einer reinen 'len()' -Funktion. Doing 'len.call (arr)' ist keine Option für mich, da ich 'call()' nicht verwenden sollte. Ich sollte in der Lage sein, Anruf vorher zu definieren, so dass ich nur den Funktionsaufruf 'len' benötige. Außerdem würde das letzte Beispiel nicht funktionieren, da andere iterierbare Objekte wie "arguments" und "strings", an denen dies arbeiten könnte, nicht berücksichtigt werden. – qarthandso

+1

Ich habe gemerkt, dass ich das verpasst habe und einen Edit am Ende hinzugefügt habe - habe ich es diesmal richtig verstanden? – quercy

+0

Sehr cool. Vielen Dank. Könnten Sie mich mit Artikeln über 'Function.prototype.apply' verlinken, die Ihnen geholfen haben? Ich bin immer noch sehr unsicher, wie das funktioniert. Aus irgendeinem Grund machen 'Array.prototype.slice.call (str)', 'String.prototype' und andere eingebaute Prototyp-Konzepte für mich Sinn. Aus irgendeinem Grund stolpern mich "Function.prototype" -Konzepte. – qarthandso