2010-01-19 7 views
62

Warum funktioniert das (returns "eins, zwei, drei"):Warum funktioniert .join() nicht mit Funktionsargumenten?

var words = ['one', 'two', 'three']; 
$("#main").append('<p>' + words.join(", ") + '</p>'); 

und diese Arbeit (returns "die Liste: 111"):

var displayIt = function() { 
    return 'the list: ' + arguments[0]; 
} 
$("#main").append('<p>' + displayIt('111', '222', '333') + '</p>'); 

aber nicht diese (kehrt leer):

var displayIt = function() { 
    return 'the list: ' + arguments.join(","); 
} 
$("#main").append('<p>' + displayIt('111', '222', '333') + '</p>'); 

Was habe ich zu meinem „Argumente“ Variable zu tun zu verwenden .join() auf, es zu sein?

+0

See: http://stackoverflow.com/questions/1424710/why-is-my-join-on-a-javascript- array-failing – Shog9

+0

Ich habe meine Antwort geändert, um Ihre aktualisierte Frage zu berücksichtigen - speziell die Frage "Was muss ich tun, damit dies funktioniert?" Teil. –

Antwort

80

Es funktioniert nicht, weil das arguments Objekt kein Array ist, obwohl es so aussieht. Es hat keine join Methode:

>>> var d = function() { return '[' + arguments.join(",") + ']'; } 
>>> d("a", "b", "c") 
TypeError: arguments.join is not a function 

Um arguments in ein Array zu konvertieren, können Sie tun:

var args = Array.prototype.slice.call(arguments); 

Jetzt join funktioniert:

>>> var d = function() { 
    var args = Array.prototype.slice.call(arguments); 
    return '[' + args.join(",") + ']'; 
} 
>>> d("a", "b", "c"); 
"[a,b,c]" 

Alternativ können Sie jQuery verwenden makeArray, die versuchen werden, "fast-arrays" wiezu drehenin Arrays:

var args = $.makeArray(arguments); 

Hier ist, was die Mozilla reference (mein Lieblings Ressource für diese Art der Sache) dazu zu sagen hat:

The arguments object is not an array. It is similar to an array, but does not have any array properties except length . For example, it does not have the pop method. ...

The arguments object is available only within a function body. Attempting to access the arguments object outside a function declaration results in an error.

+3

oder 'Array.join (Argumente,", ")' (wie 'Array.forEach (Argumente, Funktion);') – Anonymous

+0

Was passiert, wenn eines Ihrer Argumente ein Objekt ist? – user1876508

+3

@Anonymous TypeError: Objektfunktion Array() {[native Code]} hat keine Methode 'Join' – drAlberT

0

arguments ist kein jQuery-Objekt, nur ein normales JavaScript-Objekt. Erweitern Sie es, bevor Sie versuchen, .join() aufzurufen. Ich glaube, Sie würden schreiben:

return 'the list:' + $(arguments)[0]; 

(Ich bin nicht allzu vertraut mit jQuery, nur Prototype, so dass ich hoffe, dass dies nicht völlig falsch ist.)

Edit: Es ist falsch! Aber in seiner Antwort beschreibt Doug Neiner, was ich zu erreichen versuche.

+2

Das ist nicht ganz richtig; 'Argumente' ist kein Array. Stattdessen ist es ein "Array-ähnliches Objekt". –

+0

Ein normales JS-Array unterstützt 'Join'. –

+0

Wenn Argumente kein Array sind, wie kommen dann Argumente [0] und Argumente [1] mir die richtigen Werte an die Funktion übergeben? –

2

einfach die Nutzenfunktion jQuery makeArray

arguments ist kein Array, es ist ein Objekt. Aber da es so "Array-like", können Sie die Nutzenfunktion jQuery nennen makeArray, damit es funktioniert:

var displayIt = function() { 
    return 'the list: ' + $.makeArray(arguments).join(","); 
} 
$("#main").append('<p>' + displayIt('111', '222', '333') + '</p>'); 

Welche Ausgang:

<p>the list: 111,222,333</p> 
1

Sie typeof verwenden können, um zu sehen, was los ist hier:

>>> typeof(['one', 'two', 'three']) 
"object" 
>>> typeof(['one', 'two', 'three'].join) 
"function" 
>>> typeof(arguments) 
"object" 
>>> typeof(arguments.join) 
"undefined" 

hier können Sie das typeof returns „Objekt“ in beiden Fällen sehen, aber nur eines der Objekte hat eine Join-Funktion definiert.

19

Wenn Sie auf anderen Array.prototype Methoden nicht interessiert sind, und Sie wollen einfach join verwenden, können Sie es direkt aufrufen, ohne sie in ein Array zu konvertieren:

var displayIt = function() { 
    return 'the list: ' + Array.prototype.join.call(arguments, ','); 
}; 

Auch könnten Sie nützlich zu wissen, dass Das Komma ist das Standardtrennzeichen. Wenn Sie kein Trennzeichen definieren, wird das Komma mit spec verwendet.

+0

+1 Dies ist die schnellste und sicherste Antwort * WENN * alles was Sie wollen, ist Join aufzurufen, anstatt ein neues Array zu erstellen. Das Aufrufen von slice nur zum Verknüpfen teilt Speicher zu, wenn Join auch auf array-ähnlichen Objekten arbeitet. – Ajax

0

Ich weiß nicht, ob es eine einfache Art und Weise die Argumente in ein Array zu konvertieren, aber Sie können versuchen, diese:

var toreturn = "the list:"; 
for(i = 0; i < arguments.length; i++) 
{ 
    if(i != 0) { toreturn += ", "; } 
    toreturn += arguments[i]; 
} 
2

Sie könnten diese jQuery .joinObj Extension/Plugin verwende ich gemacht.

Wie Sie in dieser Geige sehen werden, können Sie es verwenden, wie folgt:

$.joinObj(args, ","); 

oder

$.(args).joinObj(","); 

Plugin-Code:

(function(c){c.joinObj||(c.extend({joinObj:function(a,d){var b="";if("string"===typeof d)for(x in a)switch(typeof a[x]){case "function":break;case "object":var e=c.joinObj(a[x],d);e!=__proto__&&(b+=""!=b?d+e:e);break;default:"selector"!=x&&"context"!=x&&"length"!=x&&"jquery"!=x&&(b+=""!=b?d+a[x]:a[x])}return b}}),c.fn.extend({joinObj:function(a){return"object"===typeof this&&"string"===typeof a?c.joinObj(this,a):c(this)}}))})(jQuery); 
+2

und ... warum die -1? Das ist ein funktionierender Plug, der genau so funktioniert wie er gefragt ist? – SpYk3HH

+3

ich hasse es auch, wenn Leute -1 mein Beitrag ohne Erklärung .. +1 für Sie .. T^T – Kokizzu

0

Bei der Moment können Sie Array-Argumente nicht verbinden, weil sie keine sind Array, shown here

so müssen Sie entweder zuerst in einem Array drehen wie diese,

function f() { 
    var args = Array.prototype.slice.call(arguments, f.length); 
    return 'the list: ' + args.join(','); 
} 

oder wie dieser, ein bisschen kürzer

function displayIt() { 
    return 'the list: ' + [].join.call(arguments, ','); 
} 

, wenn Sie so etwas wie babel verwenden oder ein kompatibler Browser, um ES6-Funktionen zu verwenden, können Sie dies auch mit Restargumenten tun.

function displayIt(...args) { 
    return 'the list: ' + args.join(','); 
} 

displayIt('111', '222', '333'); 

, die Sie würden tun lassen noch cooler Sachen wie

function displayIt(start, glue, ...args) { 
    return start + args.join(glue); 
} 

displayIt('the start: ', '111', '222', '333', ','); 
Verwandte Themen