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?

Anders Nygaard
sumber
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 .

Nick Craver
sumber
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

Walter Chapilliquen - wZVanG
sumber
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.

Wayne
sumber
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
Jaber Alshami
sumber