JavaScript terus mengejutkan saya dan ini adalah contoh lain. Saya baru saja menemukan beberapa kode yang saya tidak mengerti pada awalnya. Jadi saya debug dan datang ke temuan ini:
alert('a'['toUpperCase']()); //alerts 'A'
Sekarang ini harus jelas jika toUpperCase()
didefinisikan sebagai anggota tipe string, tetapi pada awalnya tidak masuk akal.
Bagaimanapun,
- apakah ini berhasil karena
toUpperCase
merupakan anggota 'a'? Atau ada hal lain yang terjadi di balik layar? yang kode saya membaca memiliki fungsi sebagai berikut:
function callMethod(method) { return function (obj) { return obj[method](); //**how can I be sure method will always be a member of obj** } } var caps2 = map(['a', 'b', 'c'], callMethod('toUpperCase')); // ['A','B','C'] // ignoring details of map() function which essentially calls methods on every // element of the array and forms another array of result and returns it
Hal ini fungsi agak generik untuk memanggil APAPUN metode pada APAPUN objek. Tetapi apakah itu berarti metode yang ditentukan sudah akan menjadi anggota implisit dari objek yang ditentukan?
Saya yakin bahwa saya kehilangan beberapa pemahaman serius tentang konsep dasar fungsi JavaScript. Tolong bantu saya untuk memahami ini.
javascript
function
Mahesha999
sumber
sumber
arr[5]
. Jika nomor di mana nama-nama identifier yang valid Anda bisa menggunakan notasi titik:arr.5
.5['toString']()
.Jawaban:
Untuk memecahnya.
.toUpperCase()
adalah metodeString.prototype
'a'
adalah nilai primitif, tetapi akan dikonversi menjadi representasi Object -nyaBegitu
adalah akses melalui notasi braket pada properti
toUpperCase
, dariString.prototype
. Karena properti ini mereferensikan metode , kami dapat memohonnya dengan melampirkan()
sumber
foo.bar
danfoo['bar']
sama sehingga kode yang Anda posting sama denganSaat menggunakan
foo[bar]
(perhatikan bahwa tidak ada tanda kutip) Anda tidak menggunakan nama literalbar
tetapi nilai apa pun yangbar
dikandung variabel . Jadi, menggunakanfoo[]
notasi alih-alihfoo.
memungkinkan Anda menggunakan nama properti dinamis.Mari kita lihat
callMethod
:Pertama-tama, ia mengembalikan fungsi yang diambil
obj
sebagai argumennya. Ketika fungsi itu dieksekusi akan memanggilmethod
objek itu. Jadi metode yang diberikan hanya perlu ada padaobj
dirinya sendiri atau di suatu tempat di rantai prototipe.Dalam hal
toUpperCase
metode itu berasalString.prototype.toUpperCase
- itu akan agak bodoh untuk memiliki salinan terpisah dari metode untuk setiap string yang ada.sumber
Anda dapat mengakses anggota objek apa pun dengan
.propertyName
notasi atau["propertyName"]
notasi. Itu adalah fitur bahasa JavaScript. Untuk memastikan bahwa anggota ada di objek, cukup periksa, jika sudah ditentukan:sumber
Pada dasarnya javascript memperlakukan segala sesuatu sebagai Obyek, atau lebih tepatnya setiap objek dapat dilihat sebagai kamus / array asosiatif. Dan fungsi / metode didefinisikan dengan cara yang sama persis untuk objek - sebagai entri dalam array asosiatif ini.
Jadi pada dasarnya, Anda mereferensikan / memanggil (perhatikan ' () ') properti 'toUpperCase', dari objek 'a' (yang merupakan tipe string, dalam hal ini).
Inilah beberapa kode di bagian atas kepala saya:
sumber
anyObject['anyPropertyName']
sama sepertianyObject.anyPropertyName
ketikaanyPropertyName
karakter tidak bermasalah.Lihat Bekerja dengan Objek , dari MDN.
The
toUpperCase
Metode melekat ke tipe String. Saat Anda memanggil fungsi pada nilai primitif, di sini'a'
, fungsi itu dipromosikan secara otomatis ke objek, di sini sebuah String :Anda dapat melihat fungsi yang ada dengan masuk
String.prototype.toUpperCase
.sumber
Jadi dalam Javascript,
objects
adalahobjects
. Itulah sifat mereka{}
. Properti objek dapat diatur menggunakan salah satu dari ini:a.greeting = 'hello';
ataua['greeting'] = 'hello';
. Keduanya bekerja.Pengambilan bekerja sama.
a.greeting
(tanpa tanda kutip) adalah'hello'
,a['greeting']
adalah'hello'
. Pengecualian: jika properti adalah angka, hanya metode braket yang berfungsi. Metode dot tidak.Jadi
'a'
adalah objek dengan'toUpperCase'
properti yang sebenarnya merupakan fungsi. Anda dapat mengambil fungsi dan memanggilnya selanjutnya dengan cara:'a'.toUpperCase()
atau'a'['toUpperCase']()
.Tapi apakah cara yang lebih baik untuk menulis fungsi peta adalah sebagai
var caps = ['a','b','c'].map( function(char) { return char.toUpperCase(); } )
Siapa yang butuh
callMethod
fungsi itu?sumber
Setiap objek JavaScript adalah tabel hash sehingga Anda dapat mengakses anggotanya dengan menentukan kunci. misalnya, jika variabel adalah string, maka harus memiliki fungsi toUpperCase. Jadi, Anda bisa memintanya
jadi, dengan inline str, Anda bisa memiliki di bawah ini
sumber
toUpperCase adalah metode javascript standar: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/toUpperCase
Alasan kerjanya
'a'['toUpperCase']()
adalah bahwa fungsi toUpperCase adalah properti dari objek string'a'
. Anda bisa mereferensikan properti pada objek menggunakanobject[property]
atauobject.property
. Sintaks 'a''toUpperCase' menunjukkan Anda mereferensikan propert 'toUppercase' dari objek string 'a', dan kemudian memanggilnya ().sumber
Tidak. Seseorang bisa lewat di objek itu
toUpperCase
; atautoUpperCase
yang bukan fungsiDalam kasus pertama, kesalahan akan terjadi karena mengakses properti yang tidak ada kembali
undefined
, dan kami tidak dapat memanggilundefined
sebagai fungsi.Dalam kasus kedua, kesalahan akan terjadi karena sekali lagi, kami tidak dapat menjalankan fungsi yang tidak berfungsi.
Ingat bahwa JavaScript adalah bahasa yang diketik dengan sangat longgar. Pemeriksaan tipe sedikit atau tidak ada terjadi kecuali dan sampai harus. Kode yang Anda perlihatkan berfungsi dalam kasus-kasus tertentu karena, dalam kasus-kasus itu, objek yang dikirimkan memiliki properti bernama
toUpperCase
, yang merupakan fungsi.Fakta bahwa
obj
argumen tersebut tidak dijamin memiliki jenis properti yang tepat tidak mengganggu JavaScript sama sekali. Itu mengadopsi sikap "tunggu dan lihat", dan tidak melemparkan kesalahan sampai masalah yang sebenarnya terjadi pada waktu berjalan.sumber
Hampir semua yang ada di javascript dapat diperlakukan sebagai objek. Dalam kasus Anda, alfabet itu sendiri bertindak sebagai objek string dan
toUpperCase
dapat dipanggil sebagai metode. Kurung kotak hanyalah cara alternatif untuk mengakses properti objek dan karenatoUpperCase
merupakan metode maka simplebracket()
diperlukan di sebelah['toUpperCase']
pembentukan['toUpperCase']()
.'a'['toUpperCase']()
setara dengan'a'.toUpperCase()
sumber
Hal penting yang perlu diperhatikan di sini adalah, karena Javascript adalah bahasa yang dinamis , setiap objek pada dasarnya hanyalah peta hash yang dimuliakan ( dengan beberapa pengecualian ). Dan segala sesuatu dalam objek Javascript dapat diakses dengan dua cara - notasi braket dan notasi titik.
Saya akan segera membahas dua notasi yang menjawab bagian pertama dari pertanyaan Anda, dan kemudian saya akan sampai ke bagian kedua.
Notasi braket
Mode ini lebih mirip dengan mengakses hashmaps dan array dalam bahasa pemrograman lain. Anda dapat mengakses komponen apa pun (data (termasuk objek lain) atau fungsi) menggunakan sintaks ini.
Inilah yang Anda lakukan dalam contoh Anda. Anda miliki
'a'
, yang merupakan string (dan bukan karakter literal, seperti itu akan dalam bahasa seperti C ++).Menggunakan notasi braket, Anda mengakses
toUpperCase
metodenya. Tetapi mengaksesnya masih belum cukup; cukup mengetikalert
, misalnya, dalam Javascript, tidak memanggil metode. Itu hanya pernyataan sederhana. Untuk memanggil fungsi, Anda perlu menambahkan tanda kurung:alert()
menunjukkan kotak dialog sederhana yang berisiundefined
, karena tidak menerima parameter. Kami sekarang dapat menggunakan pengetahuan ini untuk menguraikan kode Anda, yang menjadi:Yang jauh lebih mudah dibaca.
Sebenarnya, cara yang baik untuk memahami ini sedikit lebih baik adalah dengan mengeksekusi Javascript berikut:
Ini panggilan
alert
dengan melewatkannya objek fungsi, jugaalert
, tanpa juga menjalankan peringatan kedua. Apa yang ditampilkan (setidaknya di Chrome 26) adalah sebagai berikut:Panggilan:
menampilkan dua kotak pesan berurutan yang berisi
undefined
. Ini mudah dijelaskan: bagian dalamalert()
dieksekusi pertama kali, menunjukkanundefined
(karena tidak memiliki parameter apa pun) dan tidak mengembalikan apa pun. Lansiran luar menerima nilai balik lansiran batin - yang bukan apa-apa, dan juga ditampilkanundefined
di kotak pesan.Cobalah semua kasing di jsFiddle!
Notasi dot
Ini adalah pendekatan yang lebih standar, yang memungkinkan anggota objek diakses menggunakan
.
operator dot ( ). Ini akan menjadi seperti apa kode Anda dalam notasi titik:Jauh lebih mudah dibaca. Jadi kapan kita harus menggunakan notasi titik, dan kapan kita harus menggunakan notasi braket?
Perbandingan
Perbedaan utama antara kedua metode ini adalah semantik. Ada juga beberapa detail lain, tetapi saya akan sampai di sana sebentar lagi. Yang paling penting adalah apa yang sebenarnya ingin Anda lakukan - aturan praktisnya adalah Anda menggunakan notasi titik untuk bidang yang sudah mapan dan metode yang dimiliki objek, dan notasi braket ketika Anda benar-benar menggunakan objek Anda sebagai peta hash .
Contoh yang bagus tentang mengapa aturan ini sangat penting dapat ditunjukkan dalam contoh Anda - karena kode menggunakan notasi braket di tempat di mana notasi titik jauh lebih masuk akal, itu membuat kode lebih sulit dibaca. Dan itu hal yang buruk, karena kode dibaca lebih banyak daripada yang tertulis .
Dalam beberapa kasus, Anda harus menggunakan notasi braket walaupun menggunakan notasi titik lebih masuk akal:
Jika anggota objek memiliki nama yang mengandung satu atau lebih spasi atau karakter khusus lainnya, Anda tidak dapat menggunakan notasi titik:
foo.some method()
tidak berfungsi, tetapifoo["some method"]()
tidak;jika Anda perlu mengakses anggota objek secara dinamis, Anda juga terjebak menggunakan notasi braket;
Contoh:
Intinya adalah bahwa Anda harus menggunakan sintaks braket saat menggunakan objek sebagai peta hash (
foods["burger"].eat()
) dan sintaksis titik ketika bekerja dengan bidang dan metode "aktual" (enemy.kill()
). Dengan Javascript menjadi bahasa yang dinamis, garis antara bidang "aktual" dan metode suatu objek dan data "lainnya" yang disimpan di dalamnya bisa menjadi cukup buram. Tetapi selama Anda tidak mencampurnya dengan cara yang membingungkan, Anda harus baik-baik saja.Sekarang, ke sisa pertanyaan Anda (akhirnya!: P).
Kamu tidak bisa Cobalah. Cobalah untuk memanggil
derp
sebuah string. Anda akan mendapatkan kesalahan di baris:Ya, dalam kasus Anda itu harus. Kalau tidak, Anda berakhir dengan kesalahan yang saya sebutkan di atas. Namun, Anda tidak harus menggunakan
return obj[method]();
dalamcallMethod()
fungsi. Anda dapat menambahkan fungsionalitas Anda sendiri yang kemudian digunakan oleh fungsi peta. Inilah metode hard-coded yang mengubah semua huruf menjadi huruf besar:Kode dalam tutorial yang Anda tautkan menggunakan fungsi parsial . Mereka konsep yang rumit sendiri. Membaca lebih banyak tentang subjek itu akan membantu memperjelas hal-hal yang saya tidak bisa membuatnya.
Catatan: ini adalah kode fungsi peta yang digunakan oleh kode dalam pertanyaan, sumber di sini .
sumber
Jika Anda bertanya bagaimana cara kerjanya, itulah cara saya membacanya. Ok ini adalah fungsi matematika sederhana. Untuk memahaminya, Anda perlu melihat tabel ascii. Yang menetapkan nilai numerik untuk setiap huruf. Untuk terselubung para pesaing cukup menggunakan pernyataan logika untuk tersembunyi jadi misalnya If (ChcrValue> 80 && charValue <106) // Ini adalah himpunan huruf kecil kemudian charValue = charValue - 38; // jarak antara set bawah dan set atas
sesederhana itu, saya sebenarnya tidak repot-repot mencari nilai yang benar namun ini pada dasarnya menggeser semua huruf kecil ke nilai huruf besar.
sumber
'a'['toUpperCase']()
bekerja. Tetapi kesalahpahaman itu bisa dimengerti, jika seseorang tidak membaca pertanyaan itu.text-transform: uppercase
yang ditambahkan, saya akhirnya kehabisan akal bagaimana JS berhasil mengubah kasus ini, menghilangkan keraguan dan belajar satu atau dua hal. Terima kasih banyak.