
Jalur saya yang kurang lebih serius dalam pemrograman dimulai dengan menulis program dalam C #, kadang-kadang saya mencoba untuk menulis dalam JavaScript, dan sekarang dan kemudian jatuh ke dalam keadaan pingsan dalam situasi di mana saya salah menunjukkan nama variabel dan mengetahui tentang hal itu nanti bertahun-tahun satu jam debugging, karena saya tidak dekat kompiler saya, yang akan membantu saya keluar di masa-masa sulit. Setelah beberapa waktu, selain C #, saya mulai menulis banyak kode JavaScript dan sekarang saya bisa melakukannya tanpa banyak kesulitan, saya tidak lagi bingung dengan casting tipe implisit dan pengetikan dinamis.
Dalam artikel ini, saya ingin mensistematisasikan pengetahuan dasar saya tentang bahasa-bahasa ini dan mempertimbangkan persamaan dan perbedaannya. Artikel ini dapat berfungsi sebagai panduan bagi pengembang C # yang ingin mempelajari JavaScript dan sebaliknya. Saya juga ingin mencatat bahwa artikel ini menjelaskan kemampuan JS sisi klien, karena saya tidak memiliki pengalaman pengembangan di Node.js. Jadi, jika Anda masih belum kehilangan minat, mari kita mulai.
Modul Namespace dan js
Di setiap program, untuk menghindari konflik atas nama variabel, fungsi, kelas atau objek lain, kami menggabungkannya di beberapa area. Dengan demikian, jika dua area berbeda mengandung elemen dengan nama yang sama, tidak akan terjadi konflik.
Di C #, ruang nama digunakan untuk membagi program menjadi beberapa bagian. Kata kunci namespace
digunakan untuk mendeklarasikannya. Misalnya, jika kita ingin membuat satu set komponen antarmuka pengguna, masuk akal untuk menempatkan semuanya dalam satu ruang nama, misalnya, Components
. Sudah menjadi kebiasaan bahwa namespace memiliki penamaan berikut [AssemblyName].[DirectoryName].[DirectoryName].[...]
. Di setiap file, kelas komponen antarmuka pengguna harus ditempatkan di dalam namespace:
Isi file ComboBox.cs
:
namespace AssemblyName.Components { public class ComboBox {
Untuk mulai menggunakan komponen, Anda perlu mengimpornya dari namespace sebagai berikut using AssemblyName.Components
. Dengan metode koneksi satu baris ini, kami mengimpor semua objek ke file saat ini.
JS menggunakan modul ES untuk tujuan yang sama. Saat menggunakannya, kami sedikit banyak meniru perilaku namespaces dengan menulis kode tambahan. Pertimbangkan contoh yang sama dengan pustaka komponen. Katakanlah kita memiliki folder Components
, yang berisi komponen-komponen antarmuka pengguna ComboBox.js
, Button.js
, Button.js
, dll. Untuk mendapatkan perilaku serupa dibandingkan dengan namespace di folder Components
, Anda harus membuat file index.js
yang akan berisi kode berikut:
export { default as Dialog } from './ComboBox'; export { default as Button } from './Button'; export { default as Checkbox } from './Checkbox';
Untuk menggunakan komponen ini, Anda perlu mengimpornya ke file saat ini. Ini dapat dilakukan sebagai berikut: import * as Components from './../Components'
, setelah dari kata kunci, kita perlu menentukan path ke folder di mana semua komponen yang dijelaskan berada.
Cara mendeklarasikan variabel
Kata kunci var
Seperti yang Anda ketahui, C # adalah bahasa pemrograman yang sangat diketik, oleh karena itu, ketika mendeklarasikan variabel, kompiler harus mengetahui tipenya, karena ini biasanya ditunjukkan sebelum namanya.
double pi = 3.14; User user = new User(); int[] a = new[] { 0, 1, 2 };
Tetapi kita juga bisa memberi tahu kompiler bahwa ia harus menyimpulkan sendiri tipe dari ekspresi yang mengikuti tanda tugas. Ini dimungkinkan dengan memperkenalkan kata kunci var
di C # 3.0.
Dengan var
kita dapat membuat objek dengan tipe anonim:
Dalam JavaScript, Anda juga dapat menggunakan kata kunci var
untuk mendeklarasikan variabel, namun, tidak seperti C #, ruang lingkup variabel-variabel ini akan menjadi seluruh fungsi atau objek window
jika variabel tersebut dinyatakan di luar fungsi.
var a = 5 // - window function go() { var a = 6 // - go // ... }
Meskipun Anda memiliki kemampuan untuk mendeklarasikan variabel menggunakan var
dalam JavaScript, ini tidak disarankan sekarang, setelah rilis standar ES6, kata kunci let
ditambahkan, yang juga memungkinkan Anda untuk mendeklarasikan variabel, tetapi keuntungannya adalah bahwa ruang lingkupnya akan menjadi blok di mana mereka dideklarasikan, bukan seluruh fungsi.
Konstanta
Baik C # dan JavaScript menggunakan kata kunci const
untuk menyatakan bidang yang konstan. Benar, perlu dicatat bahwa konsep konstanta dalam kasus ini berbeda untuk bahasa-bahasa ini.
Dalam C #, konstanta adalah ekspresi yang dapat sepenuhnya dievaluasi pada tahap kompilasi, mis. konstanta dapat berupa angka, boolean, string, atau referensi nol ..
const int c1 = 5; const int c2 = c1 + 100; const string c3 = ""; const bool c4 = true; const User human = null; const User human = new User(firstName);
Dalam JavaScript, nilai konstanta juga tidak dapat diubah, namun, tidak ada batasan pada nilai seperti dalam C #, Anda dapat menetapkan nilai / objek / array ke dalamnya. Namun, jika suatu objek ditugaskan ke sebuah konstanta, maka konstanta itu sendiri dilindungi dari perubahan, tetapi bukan properti di dalamnya:
const c1 = 5; const c2 = c1 + 100; const c3 = ""; const c4 = true; const user = { name: "" }; user.name = "";
void
kata kunci
Saat menulis artikel ini, saya bereksperimen dengan fungsi di konsol dan kebiasaan mulai menggambarkan fungsi seperti di C # void SomeFunction...
dan itu adalah kejutan besar bagi saya ketika saya menemukan bahwa kata kunci JavaScript tidak void
. Ternyata, void
dalam JavaScript adalah operator unary yang menghitung nilai operan, lalu membuangnya dan mengembalikan yang undefined
.
alert("!"); // "!" alert(void "!"); // undefined
Dengan demikian, kita dapat mengatakan bahwa penggunaan void
jelas menunjukkan tidak adanya nilai balik, untuk detail lebih lanjut tentang contoh penggunaannya, lihat artikel selanjutnya.
Dalam C #, void
bukan operator, tetapi pada dasarnya memiliki arti yang serupa. Di sini, ini menunjukkan tidak adanya nilai pengembalian fungsi:
public void SampleMethod() {
Namun, seperti yang Anda lihat pada contoh di atas, void
di tempat di mana jenis nilai pengembalian biasanya ditunjukkan, dan ini bukan kebetulan, karena dalam C # void
juga merupakan jenis.
var t = typeof(void); t.Name
void
sebagai tipe hanya dapat digunakan dalam konteks yang tidak aman saat bekerja dengan pointer.
unsafe { void* identifier;
Kata kunci new
Dalam JavaScript, kata kunci new
adalah operator, dan digunakan dengan cara biasa untuk banyak bahasa mirip-C untuk membuat objek.
function Animal() { //... } const animal = new Animal();
Di C #, new
dapat digunakan untuk tujuan berikut:
- untuk membuat objek;
- untuk menyembunyikan anggota kelas dasar yang diwarisi;
- untuk membatasi tipe yang dapat digunakan sebagai argumen untuk parameter tipe dalam kelas generik.
Kasus pertama mirip dengan menggunakan new
dalam JavaScript.
class Animal {
Tipe data dasar
Setiap bahasa memiliki tipe data - primitif berdasarkan tipe data lainnya dibangun, mari kita lihat tipe data yang diberikan kepada kita dalam C # dan JavaScript.
Jenis C # primitif:
sbyte
bulat sbyte
: sbyte
, short
, int
, long
- Bilangan bulat tak
ushort
: byte
, ushort
, uint
, ulong
- Karakter Unicode:
char
- Kumpulan karakter Unicode:
char
- Nomor titik
float
: float
, double
- Desimal Desimal:
decimal
- Nilai Boolean:
bool
Kelas dasar adalah Object
.
Untuk JS:
Jenis data primitif:
- Nomor
number
- String
string
- Boolean
boolean
null
khusus- Arti khusus
undefined
symbol
Tipe dasarnya adalah Object
.
Setelah mempelajari primitif dari kedua bahasa, kita dapat sampai pada kesimpulan berikut:
- Alih-alih satu set tipe angka yang cukup besar, JavaScript memiliki
number
tipe tunggal; - JavaScript tidak memiliki tipe
char
, melainkan menggunakan tipe string
; - Dalam kedua bahasa, tipe dasarnya adalah
Object
; - Fitur khas JS adalah bahwa
null
dan undefined
dipisahkan menjadi tipe yang terpisah, sedangkan di C # null
adalah kata kunci yang menunjukkan tidak adanya nilai. - JS memiliki tipe
symbol
, yang digunakan terutama di dalam standar JavaScript itu sendiri, agar dapat menambahkan fungsionalitas baru tanpa konflik dengan basis kode yang ada.
Sebagai aturan, sekarang ada semakin banyak aplikasi di mana perlu untuk memproses data pada klien, yang membutuhkan akurasi yang lebih besar dalam perhitungan. JavaScript saat ini tidak memiliki kemampuan BigInt
untuk bekerja dengan jumlah besar, tetapi dalam waktu dekat ini direncanakan untuk menambah jenis BigInt
. Untuk mengatasi masalah serupa di C # ada System.Numerics.BigInteger
kelas.
Pemeriksaan Tipe Objek
Pengecekan tipe adalah operasi yang cukup umum untuk sebagian besar bahasa pemrograman. Berdasarkan jenisnya, kita dapat melakukan berbagai tindakan. Sebagai contoh, perhatikan contoh kehidupan: Anda mendengar bel pintu, jika tetangga yang mabuk mendatangi Anda (objek dengan tipe Drunk Neighbor ) untuk meminjam uang, maka Anda tidak mungkin membuka pintu untuknya, tetapi jika sahabat Anda ada di belakang pintu (objek dengan tipe terbaik teman ), maka Anda jangan ragu untuk membiarkannya masuk ke apartemen. C # dan JavaScript juga menyediakan fasilitas untuk memeriksa jenis objek.
typeof
operator
Untuk informasi jenis, baik C # dan JavaScript memiliki operator typeof
. Mari kita lihat cara kerjanya dalam kedua bahasa:
Dalam C #, operator typeof
diterapkan ke tipe dan mengembalikan objek dari kelas Type
yang berisi semua informasi tipe.
namespace Zoo { public class Animal {} } Type t = typeof(Animal); t.Name
Di JS, typeof
mengembalikan string yang menunjukkan jenis operan.
typeof 30 // 'number' typeof Symbol() // 'symbol' typeof undefined // 'undefined' // typeof new Animal() // object typeof null // 'object' typeof [1,2,3] // 'object' // typeof function() {} // 'function'; typeof class C {} // 'function';
Pada contoh di atas, Anda dapat melihat beberapa fitur operator ini. Tampaknya logis jika ekspresi typeof new Animal()
akan mengembalikan string 'Animal'
, dan typeof [1,2,3]
- string Array
, namun secara paradoks, hasilnya dalam kedua kasus adalah 'object'
. Juga, karena fakta bahwa kelas-kelas di JS adalah pembungkus fungsi, tipe ekspresi typeof class C {}
akan mengembalikan 'function'
alih-alih 'class'
. Fakta menarik lainnya adalah bahwa typeof null
expression akan mengembalikan 'object'
. Dalam JavaScript, operator ini memiliki kelemahan besar: semua objek non-primitif agar terlihat sama, mereka semua memiliki jenis object
sama.
Perlu dicatat bahwa dalam JavaScript typeof
dapat diterapkan ke apa saja: objek, fungsi, kelas, dll ... Dalam C #, operator ini hanya berlaku untuk jenis.
Selain mendapatkan informasi tentang suatu jenis, terkadang bermanfaat untuk memverifikasi bahwa suatu objek termasuk jenis tertentu.
Di C # ada operator is
untuk keperluan ini.
class Person { }
Dalam JavaScript, untuk mengetahui tipe objek yang dimiliki, Anda perlu menggunakan operator - instanceof
.
function Person() {} function Programmer() {} // Programmer Person Programmer.prototype = Object.create(Person.prototype); var person = new Person(); var programmer = new Programmer(); console.log(person instanceof Person); // true console.log(person instanceof Programmer); // false console.log(programmer instanceof Person); // true console.log(programmer instanceof Programmer); // true
Boolean dan cek kosong
Hampir di mana-mana, agar tidak mendapatkan Null reference exception
, sebelum menggunakan variabel, kami memeriksanya untuk null
, dan dalam kasus JavaScript, juga untuk undefined
.
Dalam C #, kami terus-menerus melihat kode serupa:
if(user != null && String.IsNullOrEmpty(user.name)) { user.SetName(""); }
Dalam JavaScript, konstruk ini dapat ditulis agak lebih pendek. Ini disebabkan oleh fakta bahwa, tidak seperti C #, dalam JavaScript, banyak nilai kecuali false
ketika casting juga dianggap false
:
null
undefined
- "" (Baris kosong)
0
NaN
(bukan angka)
Dengan demikian, kode C # di atas dapat ditulis sebagai berikut:
if (user && !user.name) { user.setName(""); }
atau
user && !user.name && user.setName("");
Karena fakta bahwa cek null
ada di mana-mana, Operator Propagasi Null ditambahkan dalam C # 6.0 .?
.
Kode C #:
if (user != null && user.parent != null && user.parent.parent != null) { user.parent.parent.SetName(""); }
Dengan bantuannya, bagian kode ini dapat ditulis ulang sebagai berikut:
user?.parent?.parent?.SetName("");
Dalam JavaScript, biasanya dilakukan sebagai berikut:
user && user.parent && user.parent.parent && user.parent.parent.setName("");
Menetapkan nilai default
Operasi umum lainnya adalah untuk menetapkan nilai default, dari versi 2.0 di C # Null Coalescing Operator muncul - ??
.
Dua baris kode C # berikut ini setara:
var name = user != null && user.name != null ? user.name : ""; var name = user?.name ?? "";
Dalam JavaScript, operasi serupa biasanya dilakukan sebagai berikut.
var name = user && user.name || "";
Namun, kita dapat menggunakan operator &&
dan ||
hanya jika 0
, false
dan string kosong bukan nilai yang valid.
Di masa mendatang, operator ?.
, ??
harus muncul dalam JavaScript (mereka sekarang telah melewati tahap Stage0 ), rincian lebih lanjut tentang operator ini dalam JavaScript dapat ditemukan di artikel .
Kata kunci ini
Baik C # maupun JavaScript memiliki this
. Biasanya dalam C # memahami tujuan this
adalah mudah, tetapi dalam JavaScript ini adalah salah satu konsep bahasa yang paling rumit. Selanjutnya kami akan mempertimbangkan penerapan this
pada contoh.
Di C #, this
menunjuk ke instance kelas saat ini.
class User { public string Name { get; set; } public void PrintEmployee() { Console.WriteLine(this.name); } } var employee = new Employee(); E1.PrintEmployee();
Dalam contoh ini, dalam ekspresi Console.WriteLine(this.name)
, this
menunjuk ke variabel employee
.
Karena this
adalah instance kelas saat ini, itu tidak dapat digunakan dalam metode yang tidak terikat pada jenis tertentu, misalnya, dalam metode statis.
Dalam JavaScript, this
disebut konteks panggilan dan akan ditentukan saat fungsi dipanggil. Jika Anda menjalankan fungsi yang sama dalam konteks objek yang berbeda, ia akan menerima yang berbeda this
:
var user = { firstName: "" }; var admin = { firstName: "" }; function func() { alert( this.firstName ); } user.f = func; admin.g = func; // this : user.f();
Selain itu, dalam JavaScript ada kemungkinan secara eksplisit menentukan nilai fungsi yang menggunakan this
: call
, bind
, apply
. Sebagai contoh, contoh di atas dapat ditulis ulang sebagai berikut:
var user = { firstName: "" }; var admin = { firstName: "" }; function func() { alert( this.firstName ); } // this : func.call(user); // func.call(admin); // func.bind(user)();// func.bind(admin)();//
Restrukturisasi
Seringkali diperlukan untuk menetapkan beberapa bidang objek ke variabel lokal. Misalnya, seberapa sering Anda mengamati kode yang sama?
void Method(User user) { var firstName = user.FirstName; var lastName = user.LastName;
Untuk tujuan tersebut, Anda dapat menggunakan destrukturisasi. Kedua bahasa mendukung fitur ini hingga derajat yang berbeda-beda.
C # 7.0 memperkenalkan jenis fungsi baru yang disebut dekonstruktor untuk mendukung perusakan. Untuk mendeklarasikan dekonstruktor, kita perlu mendefinisikan metode yang disebut Deconstruct
, semua parameter yang harus dideklarasikan dengan out
modifier:
class Person { public string FirstName { get; set; } public string LastName { get; set; }
Dukungan untuk perusakan atau (penugasan perusakan) dalam JavaScript muncul dalam standar EcmaScript keenam. Dengan bantuannya. Anda dapat menetapkan array atau objek ke beberapa variabel sekaligus, memecahnya menjadi beberapa bagian.
let [firstName, lastName] = ["", ""]; let [firstName, _ ] = ["", ""]; let { firstName, lastName } = { firstName: "", lastName: "" }; let { firstName } = { firstName: "", lastName: "" };
Perlu dicatat bahwa restrukturisasi dalam JavaScript memiliki lebih banyak fitur daripada di C #:
- Ubah urutan variabel;
- Tidak perlu mendeklarasikan dekonstruksi secara eksplisit;
- Array dukungan restrukturisasi;
- Menetapkan nilai default;
- Menetapkan properti suatu objek ke variabel dengan nama yang berbeda;
- Dukungan untuk penghancuran bersarang.
Kesimpulan
Pada artikel ini, kami hanya membahas konsep paling dasar dari bahasa C # dan JavaScript. Tetapi banyak aspek tetap tidak terpengaruh:
- koleksi
- fungsi
- kelas
- multithreading
Masing-masing topik ini cukup luas dan akan diungkapkan kemudian dalam artikel terpisah.