Melewati argumen ke fungsi javascript lainnya


386

Saya sudah mencoba yang berikut ini tanpa hasil:

function a(args){
    b(arguments);
}

function b(args){
    // arguments are lost?
}

a(1,2,3);

Dalam fungsi a, saya dapat menggunakan kata kunci argumen untuk mengakses array argumen, dalam fungsi b ini hilang. Apakah ada cara meneruskan argumen ke fungsi javascript lain seperti yang saya coba lakukan?


3
@ BobStein-VisiBone Setuju. Plus, perhatikan bahwa sebenarnyaarguments bukan array (melainkan objek yang mengimplementasikan semantik mirip array ) dan oleh karena itu tidak sepenuhnya jelas pada pandangan pertama apakah dapat digunakan dengan cara yang sama seperti array aktual.
Jules

@ Jules masih memilih untuk membuka kembali setelah bertahun-tahun. Apa lencana untuk membakar karya berharga orang lain? Banyak dari mereka untuk berkeliling.
Bob Stein

Jawaban:


542

Gunakan .apply()untuk memiliki akses yang sama ke argumentsdalam fungsi b, seperti ini:

function a(){
    b.apply(null, arguments);
}
function b(){
   alert(arguments); //arguments[0] = 1, etc
}
a(1,2,3);​

Anda dapat mengujinya di sini .


21
@ Brett - Anda dapat menyalinnya ke dalam array kemudian memanipulasi itu sebelum meneruskannya, misalnya:var copy = [].slice.call(arguments); <remove what you want> myFunc.apply(this, copy);
Nick Craver

18
tetapi menggunakan applyseperti ini mungkin mengacaukan ruang lingkup b(jika itu beberapa fungsi bagian dalam objek misalnya)
vsync

3
@vsync poin bagus, tetapi masalah mudah dipecahkan: meneruskan objek sebagai argumen pertama yang diterapkan.
Tad Lispy

11
tidak masuk akal untuk menggunakan "argumen" dan "argumen" bersama ...
Bung

3
Tapi kemudian "ini" mungkin diubah menjadi sesuatu selain yang asli b ini.
trusktr

223

Operator yang tersebar

Operator spread memungkinkan ekspresi diperluas di tempat-tempat di mana banyak argumen (untuk panggilan fungsi) atau beberapa elemen (untuk liter array) diharapkan.

ECMAScript ES6 menambahkan operator baru yang memungkinkan Anda melakukan ini dengan cara yang lebih praktis: ... Sebarkan Operator .

Contoh tanpa menggunakan applymetode:

function a(...args){
  b(...args);
  b(6, ...args, 8) // You can even add more elements
}
function b(){
  console.log(arguments)
}

a(1, 2, 3)

Note Cuplikan ini mengembalikan kesalahan sintaksis jika peramban Anda masih menggunakan ES5.

Catatan editor: Karena snippet digunakan console.log(), Anda harus membuka konsol JS browser Anda untuk melihat hasilnya - tidak akan ada hasil dalam halaman.

Ini akan menampilkan hasil ini:

Gambar argumen operator Spread contoh

Singkatnya, operator spread dapat digunakan untuk tujuan yang berbeda jika Anda menggunakan array, sehingga juga dapat digunakan untuk argumen fungsi, Anda dapat melihat contoh serupa dijelaskan dalam dokumen resmi: Parameter rest


6
Ini adalah operator yang sangat bagus dan saya sangat menantikan untuk menggunakannya. Namun, itu belum terjadi. Satu-satunya browser yang sudah mendukung operator spread adalah FF saat ini. Lihat tabel kompatibilitas untuk data lengkap dan terkini: kangax.github.io/compat-table/es6/#spread_%28...%29_operator
TMG

10
Mengapa itu tidak digunakan? Ini relatif mudah untuk ditranslasikan dengan babel, Anda mendapatkan semua fitur baru, dan lebih banyak kompatibilitas dengan browser lama.
adgelbfish

Ini lebih baik daripada solusi pertama karena berfungsi dalam fungsi yang ditentukan oleh operator panah.
sarfata

Anda tidak perlu ...argsdalam afungsinya. Anda bisa membuat fungsi tanpa argumen dan meneruskannya bdengan...arguments
cronoklee

1
Untuk siapa pun yang membaca jawaban ini: Bertentangan dengan komentar @ cronoklee ini, secara eksplisit menentukan ...argssebagai a's masukan dapat menjadi penting jika Anda memiliki fungsi bersarang.
Arshia001

81

Penjelasan bahwa tidak ada jawaban perlengkapan lainnya adalah bahwa argumen asli yang masih tersedia, tetapi tidak dalam posisi asli di argumentsobjek.

The argumentsobjek berisi satu elemen untuk setiap parameter yang sebenarnya disediakan untuk fungsi. Ketika Anda menelepon aAnda menyediakan tiga argumen: nomor 1, 2dan, 3. Jadi, argumentsberisi [1, 2, 3].

function a(args){
    console.log(arguments) // [1, 2, 3]
    b(arguments);
}

Ketika Anda memanggil b, namun, Anda lulus tepat satu argumen: a's argumentsobjek. Jadi argumentsmengandung [[1, 2, 3]](yaitu satu elemen, yaitu a's argumentsobjek, yang memiliki sifat yang berisi argumen asli untuk a).

function b(args){
    // arguments are lost?
    console.log(arguments) // [[1, 2, 3]]
}

a(1,2,3);

Seperti yang ditunjukkan @Nick, Anda dapat menggunakan applyuntuk menyediakan argumentsobjek yang ditetapkan dalam panggilan.

Berikut ini mencapai hasil yang sama:

function a(args){
    b(arguments[0], arguments[1], arguments[2]); // three arguments
}

Tetapi applyapakah solusi yang benar dalam kasus umum.


Jika Anda selalu melewati thiske apply?
Flimm

1
@ Flimm — ya, karena argumennya adalah argumen kedua, pasti ada sesuatu untuk argumen pertama (bisa nol ).
RobG

0

coba ini

function global_func(...args){
  for(let i of args){
    console.log(i)
  }
}


global_func('task_name', 'action', [{x: 'x'},{x: 'x'}], {x: 'x'}, ['x1','x2'], 1, null, undefined, false, true)




//task_name
//action
//(2) [{...},
//    {...}]
//    {
//        x:"x"
//    }
//(2) [
//        "x1",
//        "x2"
//    ]
//1
//null
//undefined
//false
//true
//func
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.