JavaScript'te bir diziyi işlev parametresi olarak iletme


292

Bir işlevi parametre olarak kullanarak bir işlevi çağırmak istiyorum:

const x = ['p0', 'p1', 'p2'];
call_me(x[0], x[1], x[2]); // I don't like it

function call_me (param0, param1, param2 ) {
  // ...
}

İçeriğini ait geçirerek daha iyi bir yolu var mı xiçine call_me()?

Yanıtlar:


422
const args = ['p0', 'p1', 'p2'];
call_me.apply(this, args);

İçin MDN belgelerine bakın Function.prototype.apply().


Ortam ECMAScript 6'yı destekliyorsa, bunun yerine bir yayılma argümanı kullanabilirsiniz :

call_me(...args);

9
Yan not olarak, herhangi biri bunun yerine ilişkilendirilebilir bir dizi (adlandırılmış anahtarlar) geçmek istiyorsa, bir nesne kullanın. PHP geliyor (ve her zaman google tarafından bu konu yol açtı) bu anlamaya biraz zaman aldı. Tüm nesneyi parametre olarak iletebilirsiniz. w3schools.com/js/js_objects.asp
timhc22

'Yayılma' argümanını işaret ettiğiniz için teşekkür ederiz! Bunu bilmiyordum.
Thomas An

@timhc - senin yan not yorum ilginç, ama ben ayrıştıramıyorum (ben bir çift öğreticiler aracılığıyla çalışan bir javascript noob). JS'de ilişkilendirilebilir bir dizi , birkaç öğreticiye göre bir nesnedir.
NateT

@ timhc22 ve bir işleve parametre olarak geçmek için json nesnesini kullanırken daha iyi okunabilirlik için Parametre İmhasını unutma
Muhammed Ömer Aslam

113

Neden tüm diziyi geçmiyor ve fonksiyonun içinde gerektiği gibi işlemiyorsunuz?

var x = [ 'p0', 'p1', 'p2' ]; 
call_me(x);

function call_me(params) {
  for (i=0; i<params.length; i++) {
    alert(params[i])
  }
}

37
Çünkü call_me () değiştiremiyorum. Başka bir kütüphanede tanımlanmıştır ve API ile uğraşmak mümkün değildir.
Robert

62
+1 çünkü orijinal soruya cevap vermese de, muhtemelen bu sayfayı görüntüleyen 100 bin + kişinin aradığı şey budur.
Ishikawa

Birisi "call_me (x)" hattının ne yaptığını açıklayabilir mi? Bu işlev anahtar sözcüğü olmadan bir işlev adı gibi görünüyor? Tam olarak ne yapıyor?
yüzdü

1
@swam Bu call_meişleve bir çağrıdır . Sonunda noktalı virgül yok.
SantiBailors

@swam bildirilen call_me (params) işlevini yürütüyor.
Julio Rodriguez

43

Call_me öğesinin global bir işlev olduğunu varsayarsak, bunun ayarlanmasını beklemezsiniz.

var x = ['p0', 'p1', 'p2'];
call_me.apply(null, x);


7

@KaptajnKold yanıtlamış olduğu gibi

var x = [ 'p0', 'p1', 'p2' ];
call_me.apply(this, x);

Ayrıca call_me işlevi için her parametreyi tanımlamanız gerekmez. Sadece kullanabilirsinizarguments

function call_me () {
    // arguments is a array consisting of params.
    // arguments[0] == 'p0',
    // arguments[1] == 'p1',
    // arguments[2] == 'p2'
}

4
Bu çok kötü bir uygulama ... fonksiyonun neye ihtiyacı olduğunu göremezsiniz ve fonksiyona bakarsanız her parametre isteğe bağlıdır.
Robin

3

Bunu not et

function FollowMouse() {
    for(var i=0; i< arguments.length; i++) {
        arguments[i].style.top = event.clientY+"px";
        arguments[i].style.left = event.clientX+"px";
    }

};

// ---------------------------

html sayfası

<body onmousemove="FollowMouse(d1,d2,d3)">

<p><div id="d1" style="position: absolute;">Follow1</div></p>
<div id="d2" style="position: absolute;"><p>Follow2</p></div>
<div id="d3" style="position: absolute;"><p>Follow3</p></div>


</body>

herhangi bir Args ile fonksiyon çağırabilir

<body onmousemove="FollowMouse(d1,d2)">

veya

<body onmousemove="FollowMouse(d1)">

Bu açıkça cevabın bir parçası. "argümanlar" kesinlikle çağrıdan sonra diziyi geri almak için gereklidir. Teşekkürler!
FlorianB

2

İşlev bağımsız değişkenleri de Diziler olabilir:

function foo([a,b,c], d){
  console.log(a,b,c,d);
}

foo([1,2,3], 4)

Tabii ki de forma kullanabilirsiniz :

function foo(a, b, c, d){
  console.log(a, b, c, d);
}

foo(...[1, 2, 3], 4)


2

Forma operatörünü kullanırken, iletilen son veya tek parametre olması gerektiğini unutmamalıyız. Yoksa başarısız olur.

function callMe(...arr){ //valid arguments
    alert(arr);
}

function callMe(name, ...arr){ //valid arguments
    alert(arr);
}

function callMe(...arr, name){ //invalid arguments
    alert(arr);
}

Bir diziyi başlangıç ​​argümanı olarak iletmeniz gerekiyorsa şunları yapabilirsiniz:

function callMe(arr, name){
    let newArr = [...arr];
    alert(newArr);
}

1

forma operatörünü daha temel bir biçimde kullanabilirsiniz

[].concat(...array)

dizileri döndüren ancak bağımsız değişken olarak geçmesi beklenen işlevler durumunda

Misal:

function expectArguments(...args){
  return [].concat(...args);
}

JSON.stringify(expectArguments(1,2,3)) === JSON.stringify(expectArguments([1,2,3]))

0

Cevap zaten verildi, ama sadece bir parça kek vermek istiyorum. Ulaşmak istediğiniz şey method borrowingJS bağlamında, bir nesneden bir yöntem aldığımızda ve onu başka bir nesne bağlamında çağırdığımızda denir . Dizi yöntemlerini almak ve bunları bağımsız değişkenlere uygulamak oldukça yaygındır. Sana bir örnek vereyim.

Bu nedenle, iki sayıyı bağımsız değişken olarak alan ve "süper güvenli" karma dizeyi döndüren "süper" karma işlevimiz var:

function hash() {
  return arguments[0]+','+arguments[1];
}

hash(1,2); // "1,2" whoaa

Şimdiye kadar iyi, ancak yukarıdaki yaklaşımla çok az sorunumuz var, kısıtlı, sadece iki sayı ile çalışıyor, bu dinamik değil, herhangi bir sayı ile çalışmasını sağlayalım ve bir dizi geçmek zorunda değilsiniz ( eğer hala ısrar ediyorsanız). Tamam, yeterince konuşalım, savaşalım!

Doğal çözüm arr.joinyöntemi kullanmak olacaktır :

function hash() {
  return arguments.join();
}

hash(1,2,4,..); //  Error: arguments.join is not a function

Ah adamım. Ne yazık ki, bu işe yaramaz. Çünkü hash (arguments) diyoruz ve arguments nesnesi hem yinelenebilir hem de dizi benzeri, ancak gerçek bir dizi değil. Aşağıdaki yaklaşıma ne dersiniz?

function hash() {
  return [].join.call(arguments);
}

hash(1,2,3,4); // "1,2,3,4" whoaa

Hile denir method borrowing.

joinNormal bir diziden bir yöntem ödünç alıyoruz [].join.ve [].join.callbunu bağlamında çalıştırmak için kullanıyoruz arguments.

Neden çalışıyor?

Çünkü yerel yöntemin iç algoritması arr.join(glue)çok basittir.

Şartnameden neredeyse “olduğu gibi” alınmıştır:

Let glue be the first argument or, if no arguments, then a comma ",".
Let result be an empty string.
Append this[0] to result.
Append glue and this[1].
Append glue and this[2].
Do so until this.length items are glued.
Return result.

Yani, teknik olarak bunu alır ve bunu [0], bu [1]… vb. Birleştirir. Kasıtlı olarak buna benzer dizilere izin verecek şekilde yazılmıştır (tesadüf değil, birçok yöntem bu uygulamayı takip eder). Bu yüzden aynı zamandathis=arguments.

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.