Bir işlevin tüm argümanlarını o işlevin içinde tek bir nesne olarak almak mümkün müdür?


Yanıtlar:


346

Kullanın arguments. Bir dizi gibi erişebilirsiniz. arguments.lengthBağımsız değişken sayısı için kullanın .


46
Bu yalnızca geleneksel JavaScript için geçerlidir function, ES2015 + yağ ok =>işlevleri için geçerli değildir. Olanlar için, seni kullanmak istiyorum edeceğiz ...argsşöyle fonksiyon tanımında: (...args) => console.log(args).
Sawtaytoes

141

Argümanlar olan bir dizi benzeri bir nesne (gerçek bir dizi). Örnek fonksiyon ...

function testArguments () // <-- notice no arguments specified
{
    console.log(arguments); // outputs the arguments to the console
    var htmlOutput = "";
    for (var i=0; i < arguments.length; i++) {
        htmlOutput += '<li>' + arguments[i] + '</li>';
    }
    document.write('<ul>' + htmlOutput + '</ul>');
}

Denemek...

testArguments("This", "is", "a", "test");  // outputs ["This","is","a","test"]
testArguments(1,2,3,4,5,6,7,8,9);          // outputs [1,2,3,4,5,6,7,8,9]

Tüm ayrıntılar: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Functions_and_function_scope/arguments


3
Sonucu neden buraya da göndermiyorsunuz? :)
Jonathan Azulay

2
Bu, çalışan bir kod snippet'i içerdiği ve çıktı gösterdiğinden, kabul edilen yanıttan çok daha iyidir. Kabul edilen cevap çok seyrek.
Mac

İyi cevap ... "gerçek bir dizi değil" genişleyen harika bir cevap olurdu
terpinmd

Basit bir açıklamaya bir bağlantı ekledim: "Dizi benzeri bir nesne", yalnızca "Negatif olmayan bir Tamsayı'nın length özelliğine ve genellikle bazı dizinlenmiş özelliklere sahip bir Nesne" dir. Mozilla bağlantısından: "Bir Diziye benzer, ancak uzunluk dışında herhangi bir Dizi özelliği yoktur."
Luke

31

ES6, işlev bağımsız değişkeninin "..." gösterimi ile belirtildiği bir yapıya izin verir.

function testArgs (...args) {
 // Where you can test picking the first element
 console.log(args[0]); 
}

3
Ok işlevini kullanırken bu tek yol gibi görünüyor. a = () => {console.log(arguments);}; a('foo');verir -- Uncaught ReferenceError: arguments is not defined Ancak a = (...args) => {console.log(args);}; a('foo');verir["foo"]
David Baucum

1
@DavidBaucum doğru. Çünkü arrow işlevi yeni bir kapsam oluşturmaz ve kapsamdan "argümanlar" toplanır. Ancak en kötü durum senaryosu ReferenceError değildir. Bu "argümanların" bir dış kapsamdan toplanmasıdır. Sonra bir istisna ve belki de uygulamanızda garip hatalar olsun.
pgsandstrom

1
Buna "dinlenme parametreleri" de denir, bkz. Developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… .
Dennis

21

argumentsFonksiyonlar bağımsız değişkenler depolandığı bir amacıdır.

Arguments nesnesi bir dizi gibi davranır ve ona benzer, temel olarak, dizilerin yaptığı yöntemlere sahip değildir, örneğin:

Array.forEach(callback[, thisArg]);

Array.map(callback[, thisArg])

Array.filter(callback[, thisArg]);

Array.slice(begin[, end])

Array.indexOf(searchElement[, fromIndex])

Bir argumentsnesneyi gerçek bir diziye dönüştürmenin en iyi yolunun şöyle olduğunu düşünüyorum :

argumentsArray = [].slice.apply(arguments);

Bu onu bir dizi yapar;

Yeniden kullanılabilir:

function ArgumentsToArray(args) {
    return [].slice.apply(args);
}

(function() {
   args = ArgumentsToArray(arguments);

   args.forEach(function(value) {
      console.log('value ===', value);
   });

})('name', 1, {}, 'two', 3)

sonuç:

> value === name
> value === 1
> value === Object {}
> value === two
>value === 3


1
[].slice.apply(arguments);gereksiz bir boş dizi ayırmaya neden olduğu için en iyi yol olamaz.
Thomas Eding

10

İsterseniz diziye dönüştürebilirsiniz. Dizi jenerikleri varsa:

var args = Array.slice(arguments)

Aksi takdirde:

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

dan Mozilla MDN'yi :

JavaScript motorlarında (örneğin V8) optimizasyonları önlediğinden bağımsız değişkenleri dilimlememelisiniz.


2
Güncelleme için teşekkürler. Alternatif olarak JSON.stringify ve JSON.parse komutlarını kullanın: Dizgi oluşturma function foo() { foo.bar = JSON.stringify(arguments); foo.baz = JSON.parse(foo.bar); } yerine koruma gerekiyorsa, dahili yapılandırılmış klonlama algoritmasını kullanın . DOM düğümleri iletilirse, ilgisiz bir soruda olduğu gibi XMLSerializer'ı kullanın . with (new XMLSerializer()) {serializeToString(document.documentElement) }
Paul Sweatte

7

Diğer birçok kişinin belirttiği gibi, argumentsbir işleve iletilen tüm argümanları içerir.

Aynı bağımsız değişkenlere sahip başka bir işlevi çağırmak istiyorsanız, apply

Misal:

var is_debug = true;
var debug = function() {
  if (is_debug) {
    console.log.apply(console, arguments);
  }
}

debug("message", "another argument")

4

Gunnar'a benzer bir cevap, daha eksiksiz bir örnekle: Her şeyi şeffaf bir şekilde bile iade edebilirsiniz:

function dumpArguments(...args) {
  for (var i = 0; i < args.length; i++)
    console.log(args[i]);
  return args;
}

dumpArguments("foo", "bar", true, 42, ["yes", "no"], { 'banana': true });

Çıktı:

foo
bar
true
42
["yes","no"]
{"banana":true}

https://codepen.io/fnocke/pen/mmoxOr?editors=0010


3

Evet, işlev bildirimi sırasında kaç bağımsız değişkenin mümkün olduğuna dair bir fikriniz yoksa, işlevi parametre olmadan bildirebilir ve işlev çağırma sırasında geçirilen argümanlar dizisiyle tüm değişkenlere erişebilirsiniz.


2

ES6'da böyle bir şey yapabilirsiniz:

function foo(...args) 
{
   let [a,b,...c] = args;

   console.log(a,b,c);
}


foo(1, null,"x",true, undefined);


1
Hatta `` işlev foo (a, b, ... c) {console.log (a, b, c); } ``
TitouanT

-11

ES6'da şunları kullanın Array.from:

function foo()
  {
  foo.bar = Array.from(arguments);
  foo.baz = foo.bar.join();
  }

foo(1,2,3,4,5,6,7);
foo.bar // Array [1, 2, 3, 4, 5, 6, 7]
foo.baz // "1,2,3,4,5,6,7"

ES6 olmayan kodlar için JSON.stringify ve JSON.parse komutlarını kullanın:

function foo()
  {
  foo.bar = JSON.stringify(arguments); 
  foo.baz = JSON.parse(foo.bar); 
  }

/* Atomic Data */
foo(1,2,3,4,5,6,7);
foo.bar // "{"0":1,"1":2,"2":3,"3":4,"4":5,"5":6,"6":7}"
foo.baz // [object Object]

/* Structured Data */
foo({1:2},[3,4],/5,6/,Date())
foo.bar //"{"0":{"1":2},"1":[3,4],"2":{},"3":"Tue Dec 17 2013 16:25:44 GMT-0800 (Pacific Standard Time)"}"
foo.baz // [object Object]

Dizgi oluşturma yerine koruma gerekiyorsa, dahili yapılandırılmış klonlama algoritmasını kullanın .

DOM düğümleri iletilirse, ilgisiz bir soruda olduğu gibi XMLSerializer'ı kullanın .

with (new XMLSerializer()) {serializeToString(document.documentElement) }

Bir yer işareti JSON.stringifyolarak çalışıyorsa, düzgün çalışması için her yapılandırılmış veri bağımsız değişkenini bir Hata yapıcısına sarmanız gerekebilir .

Referanslar


3
Birincisi: bu, hangi nesnelerin aktarıldığını klonlayacaktır. İkincisi: JSON'a her şey dizilemez. Yani: fonksiyonlar, DOM nesneleri, tarihler dize olarak diziliyor ...
John Dvorak

@JanDvorak Cevabımı DOM nesnelerini, işlevlerini ve tarihlerini işleyen bir işlevle düzenleyebilir misiniz?
Paul Sweatte

1
+1, hata raporlaması için argümanları bir dize olarak iletmeye çalıştığında, nesne '[object Arguments]' dizesi olarak sonlanır ve bunu konsola günlüğe kaydetme değerleri görüntülemez. OP'ye cevap vermese de soruma cevap veriyor, teşekkürler!
John
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.