Saya tahu ini digunakan untuk membuat argumen array nyata, tapi saya tidak mengerti apa yang terjadi ketika menggunakan Array.prototype.slice.call(arguments)
474
Saya tahu ini digunakan untuk membuat argumen array nyata, tapi saya tidak mengerti apa yang terjadi ketika menggunakan Array.prototype.slice.call(arguments)
Jawaban:
Apa yang terjadi di bawah tenda adalah bahwa ketika
.slice()
dipanggil secara normal,this
adalah Array, dan kemudian hanya beralih ke Array itu, dan melakukan tugasnya.Bagaimana
this
di.slice()
fungsi Array? Karena ketika Anda melakukannya:...
object
secara otomatis menjadi nilaithis
dalammethod()
. Demikian dengan:...
[1,2,3]
Array ditetapkan sebagai nilaithis
in.slice()
.Tetapi bagaimana jika Anda bisa mengganti sesuatu yang lain sebagai
this
nilainya? Selama apapun yang Anda gantikan memiliki.length
properti numerik , dan banyak properti yang merupakan indeks numerik, itu harus berfungsi. Jenis objek ini sering disebut objek seperti array .Metode
.call()
dan.apply()
membiarkan Anda secara manual mengatur nilaithis
dalam suatu fungsi. Jadi jika kita menyetel nilaithis
in.slice()
ke objek mirip array , anggap.slice()
saja itu berfungsi dengan Array, dan akan melakukan hal tersebut.Ambil objek sederhana ini sebagai contoh.
Ini jelas bukan Array, tetapi jika Anda dapat mengaturnya sebagai
this
nilai.slice()
, maka itu hanya akan berfungsi, karena terlihat cukup seperti Array untuk.slice()
dapat bekerja dengan baik.Contoh: http://jsfiddle.net/wSvkv/
Seperti yang dapat Anda lihat di konsol, hasilnya adalah apa yang kami harapkan:
Jadi inilah yang terjadi ketika Anda menetapkan
arguments
objek sebagaithis
nilai.slice()
. Karenaarguments
memiliki.length
properti dan banyak indeks numerik,.slice()
cukup berfungsi seperti bekerja pada Array nyata.sumber
Array.prototype.slice
deskripsi metode.for-in
Pernyataan yang tidak menjamin pesanan. Algoritma yang digunakan oleh.slice()
mendefinisikan urutan numerik dimulai dengan0
dan diakhiri (non-inklusif) dengan.length
objek yang diberikan (atau Array atau apa pun). Jadi pesanan dijamin konsisten di semua implementasi.var obj = {2:"two", 0:"zero", 1: "one"}
. Jika kita gunakanfor-in
untuk menyebutkan objek, tidak ada jaminan pesanan. Tetapi jika kita menggunakanfor
, kita secara manual dapat menegakkan perintah:for (var i = 0; i < 3; i++) { console.log(obj[i]); }
. Sekarang kita tahu bahwa properti objek akan tercapai dalam urutan numerik naik yang kita tetapkan olehfor
loop kita . Itu yang.slice()
dilakukannya. Tidak peduli jika ia memiliki Array yang sebenarnya. Itu baru saja dimulai0
dan mengakses properti dalam loop menanjak.The
arguments
objek adalah tidak benar-benar sebuah contoh dari Array, dan tidak memiliki metode Array. Jadi,arguments.slice(...)
tidak akan berfungsi karena objek argumen tidak memiliki metode slice.Array memiliki metode ini, dan karena
arguments
objeknya sangat mirip dengan array, keduanya kompatibel. Ini berarti bahwa kita dapat menggunakan metode array dengan objek argumen. Dan karena metode array dibangun dengan mempertimbangkan array, mereka akan mengembalikan array daripada objek argumen lainnya.Jadi mengapa digunakan
Array.prototype
? TheArray
adalah objek yang kita buat array baru dari (new Array()
), dan ini array baru lulus metode dan properti, seperti slice. Metode-metode ini disimpan dalam[Class].prototype
objek. Jadi, demi efisiensi, alih-alih mengakses metode slice dengan(new Array()).slice.call()
atau[].slice.call()
, kami hanya mendapatkannya langsung dari prototipe. Ini agar kita tidak perlu menginisialisasi array baru.Tetapi mengapa kita harus melakukan ini sejak awal? Nah, seperti yang Anda katakan, itu mengubah objek argumen menjadi contoh Array. Namun, alasan mengapa kita menggunakan slice lebih merupakan "retasan" daripada apa pun. Metode slice akan mengambil irisan array dan mengembalikan irisan itu sebagai array baru. Melewati tidak ada argumen untuk itu (selain objek argumen sebagai konteksnya) menyebabkan metode slice untuk mengambil potongan lengkap dari "array" yang diteruskan (dalam hal ini, objek argumen) dan mengembalikannya sebagai array baru.
sumber
Biasanya, menelepon
akan menyalin array
a
keb
. Namun, kami tidak bisa melakukannyakarena
arguments
bukan array nyata, dan tidak memilikislice
sebagai metode.Array.prototype.slice
adalahslice
fungsi untuk array, dancall
menjalankan fungsi denganthis
set kearguments
.sumber
prototype
? bukan metodeslice
asliArray
?Array
adalah fungsi konstruktor, dan "kelas" yang sesuai adalahArray.prototype
. Anda juga dapat menggunakan[].slice
slice
adalah metode dari setiapArray
instance, tetapi bukanArray
fungsi konstruktor. Anda gunakanprototype
untuk mengakses metode dari contoh teoritis konstruktor.Pertama, Anda harus membaca cara fungsi doa berfungsi dalam JavaScript . Saya kira itu saja sudah cukup untuk menjawab pertanyaan Anda. Tetapi inilah ringkasan dari apa yang terjadi:
Array.prototype.slice
ekstrak metode dari 's prototipe . Tetapi memanggilnya secara langsung tidak akan berhasil, karena ini adalah metode (bukan fungsi) dan karena itu memerlukan konteks (objek panggilan, ), jika tidak maka akan dibuang .slice
Array
this
Uncaught TypeError: Array.prototype.slice called on null or undefined
The
call()
Metode memungkinkan Anda untuk menentukan konteks metode ini, pada dasarnya membuat dua panggilan ini setara:Kecuali yang pertama membutuhkan
slice
metode untuk ada dalamsomeObject
rantai prototipe (seperti halnya untukArray
), sedangkan yang terakhir memungkinkan konteks (someObject
) untuk secara manual diteruskan ke metode.Juga, yang terakhir adalah kependekan dari:
Yang sama dengan:
sumber
sumber
Array.prototype.slice.call (argumen) adalah cara kuno untuk mengubah argumen menjadi array.
Di ECMAScript 2015, Anda dapat menggunakan Array.from atau operator spread:
sumber
Itu karena, seperti catatan MDN
Di sini kita memanggil
slice
objek asliArray
dan bukan pada implementasinya dan itu sebabnya tambahan.prototype
sumber
Jangan lupa, bahwa dasar-dasar tingkat rendah dari perilaku ini adalah tipe-casting yang terintegrasi dalam mesin-JS sepenuhnya.
Slice hanya mengambil objek (berkat properti arguments.length yang ada) dan mengembalikan array-objek yang dilemparkan setelah melakukan semua operasi.
Logika yang sama dengan yang Anda dapat uji jika Anda mencoba memperlakukan metode-String dengan nilai INT:
Dan itu menjelaskan pernyataan di atas.
sumber
Ia menggunakan
slice
metode array memiliki dan menyebutnya dengan yangthis
menjadiarguments
objek. Ini berarti ia memanggilnya seolah-olah Andaarguments.slice()
berasumsiarguments
memiliki metode seperti itu.Membuat slice tanpa argumen apa pun hanya akan mengambil semua elemen - jadi itu hanya menyalin elemen dari
arguments
ke array.sumber
Anggap Anda memiliki:
function.apply(thisArg, argArray )
Metode slice () memilih bagian dari array, dan mengembalikan array baru.
Jadi ketika Anda memanggil
Array.prototype.slice.apply(arguments, [0])
metode slice array dipanggil (ikat) pada argumen.sumber
Mungkin agak terlambat, tetapi jawaban untuk semua kekacauan ini adalah bahwa panggilan () digunakan dalam JS untuk warisan. Jika kita membandingkan ini dengan Python atau PHP, misalnya, panggilan digunakan masing-masing sebagai super (). init () atau parent :: _ construct ().
Ini adalah contoh penggunaannya yang menjelaskan semua:
Referensi: https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Inheritance
sumber
ketika .slice () dipanggil secara normal, ini adalah Array, dan kemudian hanya mengulangi Array itu, dan melakukan tugasnya.
sumber
Saya hanya menulis ini untuk mengingatkan diri saya sendiri ...
Atau cukup gunakan fungsi praktis ini $ A untuk mengubah sebagian besar hal menjadi sebuah array.
contoh penggunaan ...
sumber