Operasi aritmatika dalam JavaScript. Operator aritmatika Mengurutkan berdasarkan abjad




Setelah membicarakan prioritas, keterkaitan, dan isu-isu kecil lainnya, kita dapat mulai membahas operator itu sendiri. Bagian ini memberikan penjelasan tentang operator aritmatika:

Tambahan (+)
Operator plus menambahkan operan numerik atau melakukan penggabungan string. Jika salah satu operan adalah string, operan lainnya diubah menjadi string dan penggabungan dilakukan. Operan objek diubah menjadi angka atau string, yang dapat ditambahkan atau digabungkan. Konversi dilakukan menggunakan metode valueOf() dan/atau toString().

Pengurangan (−)
Jika minus digunakan sebagai operator biner, operan kedua akan dikurangi dari operan pertama. Jika operan non-numerik ditentukan, ia akan mencoba mengonversinya menjadi angka.

Perkalian (*)
Operator * mengalikan kedua operannya. Ia mencoba mengubah operan non-numerik menjadi angka.

Divisi (/)
Operator / membagi operan pertama dengan operan kedua. Upaya untuk mengubah operan non-numerik menjadi angka. Mereka yang terbiasa dengan bahasa pemrograman yang membedakan bilangan bulat dan bilangan real mungkin berharap mendapatkan hasil bilangan bulat ketika membagi satu bilangan bulat dengan bilangan bulat lainnya.

Namun, dalam JavaScript, semua angka adalah nyata, sehingga semua pembagian menghasilkan hasil floating point. Operasi 5/2 menghasilkan 2,5, bukan 2. Membagi dengan nol menghasilkan plus atau menit tak terhingga, dan 0/0 menghasilkan NaN.

Pembagian modulo (%)
Operator % menghitung sisa yang diperoleh ketika operan pertama dibagi bilangan bulat dengan operan kedua. Jika operan non-numerik diberikan, operator akan mencoba mengubahnya menjadi angka. Tanda hasil sesuai dengan tanda operan pertama. Misalnya, 5% 2 menghasilkan 1.
Operator pembagian modulo biasanya digunakan dengan operan bilangan bulat, tetapi juga berfungsi untuk nilai riil. Misalnya, -4,3% 2,1 memberikan hasil -0,1.

Unary dikurangi (−)
Ketika minus digunakan sebagai operator unary sebelum operan tunggal, ia melakukan operasi perubahan tanda unary. Dengan kata lain, ini mengubah nilai positif menjadi nilai negatif dan sebaliknya. Jika operannya bukan angka, operator ini akan mencoba mengubahnya menjadi angka.

Unary plus (+)
Untuk simetri dengan operator unary minus, JavaScript juga memiliki operator unary plus. Anda dapat menggunakan operator ini untuk secara eksplisit menentukan tanda literal numerik jika menurut Anda ini akan membuat teks program lebih mudah dipahami:
var keuntungan = +1000000;

Dalam kode seperti itu, operator plus tidak melakukan apa pun; hasil karyanya adalah makna argumentasinya.

Namun, ini mengubah argumen non-numerik menjadi angka. Jika argumen tidak dapat dikonversi, NaN dikembalikan.

Kenaikan (+)
Operator ini menambah (yaitu bertambah satu) operan tunggalnya, yang harus berupa variabel, elemen array, atau properti objek. Jika nilai variabel, elemen array, atau properti ini bukan angka, operator terlebih dahulu mencoba mengubahnya menjadi angka. Perilaku sebenarnya dari operator ini bergantung pada posisinya terhadap operan. Jika Anda meletakkannya sebelum operan (awalan operator kenaikan), maka 1 ditambahkan ke operan, dan hasilnya adalah nilai operan yang bertambah. Jika ditempatkan setelah operan (operator kenaikan postfix), maka 1 ditambahkan ke operan, tetapi hasilnya adalah nilai asli operan. Jika nilai yang bertambah bukan berupa angka, maka akan diubah menjadi angka selama proses perhitungan.

Misalnya, kode berikut menyetel variabel i dan j menjadi 2:
saya = 1;
j = ++saya;
Dan yang ini menyetel i ke 2 dan j ke 1:
saya = 1;
j = saya++;

Operator ini, dalam kedua bentuknya, paling sering digunakan untuk menaikkan counter yang mengontrol loop.

Perhatikan bahwa Anda tidak dapat menyisipkan baris baru di antara operator kenaikan awalan atau postfix dan operan sebelumnya, karena titik koma dimasukkan secara otomatis dalam JavaScript. Jika Anda melakukan ini, JavaScript akan memperlakukan operan sebagai instruksi lengkap dan menyisipkan titik koma setelahnya.

Penurunan (−−)
Operator ini mengurangi (yaitu, mengurangi sebesar 1) operan numerik tunggalnya, yang dapat berupa variabel, elemen array, atau properti objek. Jika nilai variabel, elemen, atau properti ini bukan angka, operator terlebih dahulu mencoba mengubahnya menjadi angka. Seperti halnya operator ++, perilaku sebenarnya dari operator - bergantung pada posisinya relatif terhadap operannya. Ketika ditempatkan sebelum operan, ia akan mengurangi operan dan mengembalikan nilai yang dikurangi. Setelah operan, ia mengurangi operan tetapi mengembalikan nilai aslinya.

Seringkali perhitungan dalam JavaScript tidak memberikan hasil yang kita inginkan. Tentu saja, kita dapat melakukan apapun yang kita inginkan dengan angka - membulatkan ke atas atau ke bawah, menetapkan rentang, memotong angka yang tidak perlu ke sejumlah tempat desimal tertentu, semuanya tergantung pada apa yang ingin Anda lakukan dengan angka ini di masa mendatang.

Mengapa pembulatan diperlukan?

Salah satu aspek menarik dari JavaScript adalah ia tidak benar-benar menyimpan bilangan bulat, kami langsung bekerja dengan bilangan floating point. Hal ini, dikombinasikan dengan fakta bahwa banyak nilai pecahan tidak dapat dinyatakan dalam jumlah desimal yang terbatas, dalam JavaScript kita bisa mendapatkan hasil seperti ini:

0.1 * 0.2; > 0.020000000000000004 0.3 - 0.1 > 0.19999999999999998
Untuk tujuan praktis, ketidakakuratan ini tidak menjadi masalah, dalam kasus kita, kita berbicara tentang kesalahan seperlima, namun hal ini mungkin mengecewakan beberapa orang. Kita juga bisa mendapatkan hasil yang agak aneh ketika bekerja dengan angka yang mewakili mata uang, persentase, atau ukuran file. Untuk memperbaiki ketidakakuratan ini, kita hanya perlu bisa membulatkan hasilnya, dan cukup mengatur presisi desimalnya.

Pembulatan bilangan memiliki aplikasi praktis, kita dapat memanipulasi suatu bilangan dalam rentang tertentu, misalnya kita ingin membulatkan suatu nilai ke bilangan bulat terdekat daripada hanya mengerjakan bagian desimal saja.

Pembulatan angka desimal

Untuk memotong angka desimal, gunakan metode toFixed atau toPrecision. Keduanya mengambil argumen tunggal yang menentukan, masing-masing, berapa banyak angka penting (yaitu, jumlah total digit yang digunakan dalam angka tersebut) atau tempat desimal (angka setelah koma desimal) yang harus disertakan dalam hasil:
  1. Jika argumen tidak ditentukan untuk toFixed(), argumen tersebut akan default ke nol, yang berarti 0 tempat desimal, argumen tersebut memiliki nilai maksimum 20.
  2. Jika tidak ada argumen yang diberikan pada toPrecision, angka tersebut tidak akan disentuh
misalkan RandNum = 6,25; randNum.toFixed(); > "6" Math.PI.toPrecision(1); > "3" Jumlah Rand = 87.335; randNum.toFixed(2); > "87,33" Jumlah Rand = 87,337; randNum.toPrecision(3); > "87,3"
Metode toFixed() dan toPrecision() mengembalikan representasi string dari hasil, bukan angka. Artinya ketika menjumlahkan nilai yang dibulatkan dengan randNum, maka akan menghasilkan rangkaian string, bukan jumlah angka:

Misalkan RandNum = 6,25; biarkan dibulatkan = randNum.toFixed(); // "6" console.log(randNum + bulat); > "6.256"
Jika Anda ingin hasilnya berupa tipe data numerik, Anda perlu menggunakan parseFloat:

Misalkan RandNum = 6,25; biarkan dibulatkan = parseFloat(randNum.toFixed(1)); console.log(dibulatkan); > 6.3
Harap dicatat bahwa nilai 5 dibulatkan kecuali dalam kasus yang jarang terjadi.

Metode toFixed() dan toPrecision() berguna karena tidak hanya dapat memotong bagian pecahan, namun juga menambahkan tempat desimal, yang memudahkan saat bekerja dengan mata uang:

Misalkan WholeNum = 1 Misalkan DollarCents = WholeNum.toFixed(2); console.log(dolarSen); > "1,00"
Perhatikan bahwa toPrecision akan menghasilkan hasil dalam notasi ilmiah jika jumlah bilangan bulat lebih besar dari presisi itu sendiri:

Misalkan bilangan = 123.435 bilangan.toPrecision(2); > "1.2e+2"

Cara Menghindari Kesalahan Pembulatan dengan Desimal

Dalam beberapa kasus, toFixed dan toPrecision membulatkan nilai 5 ke bawah dan ke atas:

Misalkan numTest = 1,005; numTest.toFixed(2); > "1,00"
Seharusnya hasil perhitungan di atas adalah 1,01, bukan 1. Jika ingin menghindari kesalahan serupa, kita bisa menggunakan solusi yang dikemukakan oleh Jack L Moore yang menggunakan bilangan eksponensial untuk perhitungannya:

Fungsi putaran(nilai, desimal) ( return Number(Math.round(value+"e"+desimals)+"e-"+desimals); )
Sekarang:

Bulat(1.005,2); > 1,01
Jika Anda menginginkan solusi yang lebih kuat daripada yang ditunjukkan di atas, Anda dapat mengunjungi MDN.

Pembulatan epsilon mesin

Metode alternatif untuk membulatkan bilangan desimal diperkenalkan di ES6. Pembulatan epsilon mesin memberikan margin kesalahan yang wajar saat membandingkan dua angka floating point. Tanpa pembulatan, perbandingan dapat menghasilkan hasil yang serupa dengan berikut ini:

0,1 + 0,2 === 0,3 > salah
Kami menggunakan Math.EPSILON dalam fungsi kami untuk mendapatkan perbandingan yang valid:

Fungsi epsEqu(x, y) ( return Math.abs(x - y)< Number.EPSILON * Math.max(Math.abs(x), Math.abs(y)); }
Fungsi ini mengambil dua argumen: yang pertama adalah perhitungan saat ini, yang kedua adalah hasil yang diharapkan. Ini mengembalikan perbandingan keduanya:

EpsEqu(0,1 + 0,2, 0,3) > benar
Semua browser modern sudah mendukung fungsi matematika ES6, tetapi jika Anda ingin dukungan di browser seperti IE 11, gunakan polyfill.

Memangkas bagian pecahan

Semua cara yang disajikan di atas dapat dibulatkan ke angka desimal. Untuk mengurangi suatu angka menjadi dua desimal, Anda harus mengalikannya terlebih dahulu dengan 100, lalu membagi hasilnya dengan 100:

Fungsi terpotong(angka) ( return Math.trunc(angka * 100) / 100; ) terpotong(3.1416) > 3.14
Jika Anda ingin mengadaptasi metode ini ke sejumlah tempat desimal, Anda dapat menggunakan negasi ganda bitwise:

Fungsi terpotong(angka, tempat desimal) ( biarkan numPowerConverter = Math.pow(10, tempat desimal); kembalikan ~~(num * numPowerConverter)/numPowerConverter; )
Sekarang:

Misalkan randInt = 35.874993; terpotong(randInt,3); > 35.874

Bulatkan ke angka terdekat

Untuk membulatkan angka desimal ke angka terdekat ke atas atau ke bawah, mana saja yang terdekat, gunakan Math.round():

Putaran matematika(4.3) > 4 Putaran matematika(4.5) > 5
Harap dicatat bahwa “setengah nilai”, 0,5 dibulatkan sesuai dengan aturan matematika.

Bulatkan ke bawah ke bilangan bulat terdekat

Jika Anda ingin selalu membulatkan ke bawah, gunakan Math.floor:

Matematika.lantai(42.23); > 42 Matematika.lantai(36.93); > 36
Harap diperhatikan bahwa pembulatan ke bawah dapat dilakukan untuk semua angka, termasuk angka negatif. Bayangkan sebuah gedung pencakar langit dengan jumlah lantai yang tidak terbatas, termasuk lantai di tingkat paling bawah (mewakili angka negatif). Jika Anda berada di dalam lift pada tingkat terendah antara 2 dan 3 (yang mewakili nilai -2,5), Math.floor akan membawa Anda ke -3:

Matematika.lantai(-2.5); > -3
Namun jika Anda ingin menghindari situasi ini, gunakan Math.trunc, yang didukung di semua browser modern (kecuali IE/Edge):

Matematika.trunc(-41.43); > -41
Di MDN Anda akan menemukan polyfill yang akan memberikan dukungan untuk Math.trunc di browser dan IE/Edge.

Bulatkan ke bilangan bulat terdekat

Sebaliknya, jika Anda selalu perlu melakukan pembulatan, gunakan Math.ceil. Sekali lagi, ingat elevator tak terbatas: Math.ceil akan selalu "naik", terlepas dari apakah angkanya negatif atau tidak:

Matematika.ceil(42.23); > 43 Matematika.ceil(36.93); > 37 Matematika.ceil(-36.93); > -36

Pembulatan ke atas/bawah ke angka yang diperlukan

Jika kita ingin membulatkan ke kelipatan 5 terdekat, cara termudah adalah dengan membuat fungsi yang membagi bilangan tersebut dengan 5, membulatkannya, lalu mengalikannya dengan jumlah yang sama:

Fungsi roundTo5(num) ( return Math.round(num/5)*5; )
Sekarang:

BulatKe5(11); > 10
Jika Anda ingin membulatkan nilai Anda ke kelipatan, kami menggunakan fungsi yang lebih umum, meneruskan nilai awal dan kelipatannya:

Fungsi roundToMultiple(num, multiple) ( return Math.round(num/multiple)*multiple; )
Sekarang:

Misalkan Angka awal = 11; misalkan kelipatan = 10; roundToMultiple(Nomor awal, kelipatan); > 10;

Memperbaiki nomor dalam suatu rentang

Ada banyak kasus di mana kita ingin mendapatkan nilai x yang berada dalam suatu rentang. Misalnya, kita mungkin memerlukan nilai antara 1 dan 100, namun hasilnya adalah 123. Untuk mengatasinya, kita dapat menggunakan min (mengembalikan bilangan terkecil dari sekumpulan angka) dan max (mengembalikan bilangan terbesar dari kumpulan angka mana pun) angka). Dalam contoh kita, rentangnya adalah dari 1 hingga 100:

Misalkan Batas Rendah = 1; misalkan highBound = 100; misalkan numInput = 123; biarkan dijepit = Math.max(lowBound, Math.min(numInput, highBound)); console.log(dijepit); > 100;
Sekali lagi, kita dapat menggunakan kembali operasi tersebut dan menggabungkan semuanya dalam sebuah fungsi, menggunakan solusi yang diusulkan oleh Daniel X. Moore:

Nomor.prototipe.clamp = function(min, max) ( return Math.min(Math.max(this, min), max); );
Sekarang:

NumInput.clamp(batas rendah, batas tinggi); > 100;

Pembulatan Gaussian

Pembulatan Gaussian, juga dikenal sebagai pembulatan bankir, melibatkan pembulatan ke bilangan genap terdekat. Metode pembulatan ini bekerja tanpa kesalahan statistik. Solusi yang lebih baik disarankan oleh Tim Down:

Fungsi gaussRound(angka, Tempat Desimal) ( misalkan d = Tempat Desimal || 0, m = Math.pow(10, d), n = +(d ? num * m: num).toFixed(8), i = Math.floor (n), f = n - i, e = 1e-8, r = (f > 0,5 - e && f< 0.5 + e) ? ((i % 2 == 0) ? i: i + 1) : Math.round(n); return d ? r / m: r; }
Sekarang:

GaussRound(2.5) > 2 gaussRound(3.5) > 4 gaussRound(2.57,1) > 2.6
Desimal dalam CSS:

Karena JavaScript sering digunakan untuk membuat pemetaan posisi untuk elemen HTML, Anda mungkin bertanya-tanya apa yang akan terjadi jika kita membuat nilai desimal untuk elemen kita:

#kotak (lebar: 63.667731993px; )
Kabar baiknya adalah browser modern akan menghormati nilai desimal dalam model blok, termasuk persentase atau satuan piksel.

Penyortiran

Seringkali kita harus mengurutkan beberapa elemen, misalnya, kita memiliki serangkaian catatan permainan, dan elemen tersebut harus disusun dalam urutan menurun berdasarkan peringkat pemain. Sayangnya, metode sort() standar memiliki beberapa keterbatasan yang mengejutkan: metode ini bekerja dengan baik dengan kata-kata umum dalam bahasa Inggris, namun langsung rusak ketika menemukan angka, karakter unik, atau kata-kata huruf besar.

Menyortir berdasarkan abjad

Tampaknya mengurutkan array berdasarkan abjad adalah tugas yang sederhana:

Biarkan buah = ["butternut squash", "aprikot", "melon"]; buah.sortir(); > "aprikot", "butternut squash", "melon"]
Namun, kami mengalami masalah segera setelah salah satu elemennya menjadi huruf besar:

Biarkan buah = ["butternut squash", "aprikot", "Cantalope"]; buah.sortir(); > "Blewah", "aprikot", "butternut squash"]
Hal ini karena, secara default, penyortir membandingkan karakter pertama yang direpresentasikan dalam Unicode. Unicode adalah kode unik untuk karakter apa pun, apa pun platformnya, apa pun programnya, apa pun bahasanya. Misalnya, jika Anda melihat tabel kode, karakter "a" memiliki nilai U+0061 (dalam heksadesimal 0x61), sedangkan karakter "C" memiliki kode U+0043 (0x43), yang muncul lebih awal di Unicode tabel daripada karakter "a".

Untuk mengurutkan array yang mungkin berisi huruf pertama campuran, kita perlu mengonversi semua elemen untuk sementara menjadi huruf kecil, atau menentukan urutan pengurutan menggunakan metode localeCompare() dengan beberapa argumen. Sebagai aturan, untuk kasus seperti itu, lebih baik segera membuat fungsi untuk penggunaan berulang:

Fungsi alphaSort(arr) ( arr.sort(function (a, b) ( return a.localeCompare(b, "en", ("sensitivity": "base")); )); ) biarkan buah = ["butternut squash ", "aprikot", "Blewah"]; alphaSort(buah) >
Jika Anda ingin array diurutkan dalam urutan abjad terbalik, cukup tukar posisi a dan b dalam fungsi:

Fungsi alphaSort(arr) ( arr.sort(function (a, b) ( return b.localeCompare(a, "en", ("sensitivity": "base")); )); ) biarkan buah = ["butternut squash ", "aprikot", "Blewah"]; alphaSort(buah) > ["Blewah", "butternut squash", "aprikot"]
Di sini perlu dicatat bahwa localeCompare digunakan dengan argumen, kita juga perlu ingat bahwa ini didukung oleh IE11+, untuk versi IE yang lebih lama, kita dapat menggunakannya tanpa argumen, dan dalam huruf kecil:

Fungsi caseSort(arr) ( arr.sort(function (a, b) ( return a.toLowerCase().localeCompare(b.toLowerCase()); )); ) biarkan buah = ["butternut squash", "aprikot", "Blewah"]; caseSort(buah) > ["aprikot", "butternut squash", "Blewah"]

Urutan numerik

Semua ini tidak berlaku untuk contoh yang kita bicarakan di atas tentang susunan rekaman permainan. Dengan beberapa array numerik, pengurutan berfungsi dengan baik, namun pada titik tertentu hasilnya tidak dapat diprediksi:

Misalkan skor tinggi = ; skor tinggi.sort(); >
Masalahnya adalah metode sort() melakukan perbandingan leksikografis: yang berarti bahwa angka-angka akan diubah menjadi string dan perbandingan akan dilakukan lagi dengan mencocokkan karakter pertama dari string itu dalam urutan karakter dalam tabel Unicode . Oleh karena itu, kita perlu lagi mendefinisikan urutan pengurutan kita:

Misalkan skor tinggi = ; highScores.sort(fungsi(a,b) ( kembalikan a - b; )); >
Sekali lagi, untuk mengurutkan angka dalam urutan terbalik, tukar posisi a dan b dalam fungsi tersebut.

Menyortir struktur mirip JSON

Dan yang terakhir, jika kita memiliki struktur data mirip JSON yang direpresentasikan sebagai serangkaian rekaman permainan:

Misalkan skor = [ ( "nama": "Daniel", "skor": 21768 ), ( "nama": "Michael", "skor": 33579 ), ( "nama": "Alison", "skor": 38395 ) ];
Di ES6+, Anda dapat menggunakan fungsi panah:

Skor.sort((a, b) => b.skor - a.skor));
Untuk browser lama yang tidak memiliki dukungan ini:

Scores.sort(function(a, b) ( return a.score - b.score ));
Seperti yang Anda lihat, pengurutan dalam JavaScript adalah hal yang agak tidak jelas, saya harap contoh-contoh ini akan membuat hidup lebih mudah.

Bekerja dengan fungsi daya

Eksponensial adalah operasi yang awalnya didefinisikan sebagai hasil perkalian berulang kali suatu bilangan asli dengan bilangan itu sendiri; akar kuadrat dari a adalah bilangan yang menghasilkan a jika dikuadratkan. Fungsi-fungsi tersebut dapat kita gunakan terus-menerus dalam kehidupan sehari-hari dalam pelajaran matematika, termasuk saat menghitung luas, volume, atau bahkan dalam pemodelan fisika.

Dalam JavaScript, fungsi pangkat direpresentasikan sebagai Math.pow(), dan dalam standar ES7 yang baru, operator eksponensial baru diperkenalkan - " * * ".

Eksponensial

Untuk menaikkan suatu bilangan ke pangkat ke-n, gunakan fungsi Math.pow(), dimana argumen pertama adalah bilangan yang akan dipangkatkan, argumen kedua adalah eksponen:

Matematika.pow(3,2) > 9
Bentuk notasi ini berarti 3 kuadrat, atau 3 × 3, yang menghasilkan hasil 9. Contoh lain tentu saja dapat diberikan:

Matematika.pow(5,3); > 125
Artinya, 5 pangkat tiga, atau 5 × 5 × 5, sama dengan 125.

ECMAScript 7 adalah versi JavaScript berikutnya, pada prinsipnya, kita dapat menggunakan operator eksponensial baru yang diusulkan - * *, bentuk notasi ini mungkin lebih deskriptif:

3 ** 2 > 9
Saat ini dukungan untuk operator ini cukup terbatas sehingga tidak disarankan untuk menggunakannya.

Fungsi daya dapat berguna dalam berbagai situasi. Contoh sederhana menghitung jumlah detik dalam satu jam: Math.pow (60,2).

Akar kuadrat dan kubus

Math.sqrt() dan Math.cbrt() adalah kebalikan dari Math.pow(). Seperti yang kita ingat, akar kuadrat dari a adalah bilangan yang menghasilkan a jika dikuadratkan.

Matematika.sqrt(9) > 3
Pada saat yang sama, akar pangkat tiga dari a adalah bilangan yang menghasilkan a jika dipangkatkan menjadi kubus.

Matematika.cbrt(125) > 5
Math.cbrt() baru saja diperkenalkan ke dalam spesifikasi JavaScript, dan oleh karena itu hanya didukung di browser modern: Chrome 38+, Firefox dan Opera 25+, dan Safari 7.1+. Anda akan melihat bahwa Internet Explorer tidak ada dalam daftar ini, tetapi Anda akan menemukan polyfill di MDN.

Contoh

Tentu saja, kita dapat menggunakan nilai non-integer di salah satu fungsi berikut:

Matematika.pow(1.25, 2); > 1,5625 Matematika.cbrt(56,57) > 3,8387991760286138
Harap dicatat bahwa ini juga berfungsi dengan baik ketika menggunakan nilai argumen negatif:

Matematika.pow(-5,2) > 25 Matematika.pow(10,-2) > 0,01
Namun, ini tidak berlaku untuk akar kuadrat:

Matematika.sqrt(-9) > NaN
Dari analisis matematis kita mengetahui bahwa bilangan imajiner mengacu pada akar kuadrat dari bilangan negatif. Dan ini mungkin membawa kita pada teknik lain untuk mengerjakan bilangan kompleks, tapi itu lain ceritanya.

Anda dapat menggunakan pecahan di Math.pow() untuk mencari akar kuadrat dan pangkat tiga suatu bilangan. Akar kuadrat menggunakan eksponen 0,5:

Matematika.pow(5, 0,5); // = Matematika.sqrt(5) = 5 ** (1/2) > 2.23606797749979
Namun, karena keanehan floating point, Anda tidak dapat menebak dengan tepat hasil yang benar:

Matematika.pow(2.23606797749979,2) > 5.000000000000001
Dalam situasi seperti itu, Anda harus memotong tanda dari angka atau membulatkan ke nilai tertentu.

Beberapa orang, karena alasan yang tidak diketahui, dalam JavaScript mengacaukan fungsi Math.pow() dengan Math.exp() , yang merupakan fungsi eksponensial untuk angka secara umum. Catatan: Dalam bahasa Inggris, "eksponen" diterjemahkan sebagai "eksponen", jadi ini lebih cenderung berlaku untuk penutur bahasa Inggris, meskipun ada nama alternatif untuk eksponen, seperti indeks, pangkat.

Konstanta matematika

Bekerja dengan matematika dalam JavaScript menjadi lebih mudah dengan sejumlah konstanta bawaan. Konstanta ini adalah properti dari objek Math. Perlu dicatat bahwa konstanta ditulis dalam huruf besar, bukan notasi CamelCase.

Hanya pengguna terdaftar yang dapat berpartisipasi dalam survei ini. , Silakan.

Tag: Tambahkan tag

Saya mengingatkan Anda bahwa ini kursus pengantar JavaScript untuk pemula. Hari ini kita akan melihat apa operator ada dalam JavaScript. Kencangkan sabuk pengaman! Akan ada banyak bukaf.

Jika Anda memiliki banyak data, Anda perlu melakukan sesuatu dengannya. Operator sibuk dengan bisnis. Mereka selalu menjumlahkan, mengalikan, membagi, mengurangi, membandingkan, mengapropriasi dan apapun yang mereka lakukan. Tanpa operator dalam pemrograman Anda tidak bisa memasak bubur.

JavaScript menggunakan jenis operator berikut:

  • Operator aritmatika
  • Operator Penugasan
  • Operator Perbandingan
  • Operator logika
  • Operator string
  • Pernyataan bersyarat

Ini bukan daftar lengkap, tapi ini cukup untuk membantu Anda memulai. Mari kita lihat setiap jenis operator yang disajikan, mengapa mereka dibutuhkan dan apa kegunaannya. Pergi!

Operator Aritmatika dalam JavaScript

Anda semua sudah mengenal operator aritmatika sejak sekolah. Ini adalah tanda-tanda penjumlahan, pengurangan, pembagian dan perkalian yang biasa: + , - , / , * . Oleh karena itu, mereka menjalankan fungsi yang sama dalam pemrograman seperti dalam matematika biasa. Anda tidak akan mengalami kesulitan dalam hal ini.

Data yang digunakan oleh operator disebut operan.

2 + 3 // di sini angka 2 dan 3 adalah operan, dan tanda + adalah operator penjumlahan

Seperti dalam matematika, operator aritmatika mempunyai prioritasnya sendiri: perkalian dan pembagian mempunyai prioritas lebih tinggi daripada penjumlahan dan pengurangan.

2 + 3 * 4 // perkalian dilakukan di sini terlebih dahulu, baru kemudian penjumlahan

Dan seperti dalam matematika, tanda kurung digunakan secara aktif untuk mengubah prioritas:

(2 + 3) * 4 // di sini dilakukan penjumlahan terlebih dahulu, baru kemudian perkalian

Omong-omong, tanda = juga merupakan operator. Seperti yang telah kita ketahui di artikel tentang , ini adalah operator penugasan, dan bukan tanda sama dengan sama sekali. Jangan lupakan itu!

Operator divisi modulo

Sekarang mari kita lihat operator aritmatika yang lebih menarik. Dan ikon pertama akan menjadi ikon persen - %. Dalam JavaScript, ini sama sekali bukan persentase kata. Ini adalah bagaimana pembagian modulo dilambangkan dalam pemrograman. Hasil dari operasi tersebut adalah sisa pembagian. Misalnya:

100% 22 //sisanya menjadi 12
100% 10 // sisanya akan menjadi 0

Dalam perhitungannya, operator ini mempunyai prioritas yang sama dengan perkalian dan pembagian, jadi jangan lupa untuk memberi tanda kurung.

Menggabungkan operator

Operator = dapat dan harus digabungkan dengan operator lain untuk mempersingkat notasi. Contoh:

var n = 2; // tetapkan variabel n nilai 2
n = n + 3; // tetapkan variabel n nilai baru n + 2, dapatkan 5

Hal yang sama dapat ditulis seperti ini:

var n = 2;
n += 3; // setara dengan penulisan n = n + 3

Operator kenaikan ++ dan pengurangan – ​​–

Di antara operator aritmatika ada beberapa yang sangat menarik - kenaikan Dan pengurangan. Mereka masing-masing diberi nama ++ dan ––. Yang pertama menambah variabel sebanyak satu, dan yang kedua menurunkannya. Fitur ini sangat sering digunakan dalam pemrograman karena memberikan banyak kemudahan. Paling sering ini dapat ditemukan dalam ekspresi kondisional, tetapi lebih dari itu nanti.

Kedua operator memiliki lokasi tertentu dalam catatan. Mereka bisa menjadi seperti itu awalan form (sebelum variabel) ++n , dan in postfix(setelah variabel) n++ . Perbedaannya sangat besar! Jangan pernah bingung dengan bentuk-bentuk ini dan ingatlah dengan baik. Jika operator ini muncul sebelum suatu variabel, maka sebagai hasilnya mereka meningkatkan nilainya sebesar 1. Tapi! Jika muncul setelah variabel, mereka mengembalikan nilai aslinya. Contoh:

var n = 2, m = 0;
m = ++n // menambah n sebanyak 1 (n = 3) dan menetapkan m nilai yang sama dengan 3

var n = 2, m = 3;
m = n++ // menambah n sebanyak 1 (n = 3), namun menyetel m ke nilai sebelumnya n = 2

Saya yakin Anda dapat dengan mudah memahami contoh pertama. Tapi dengan yang kedua mungkin ada masalah. Agar lebih mudah memahami hal ini dan tidak bingung, bayangkan saja Anda terlebih dahulu menetapkan nilai variabel n ke variabel m, dan baru setelah itu nilai n bertambah satu. Pada contoh pertama, pertama-tama Anda menaikkan nilai n sebanyak satu, lalu menetapkan nilai ini ke variabel m.

Itu saja untuk operator aritmatika. Tentu saja, masih banyak lagi variasi dan seluk-beluk penggunaan operator sederhana ini, namun ini sudah lebih dari cukup bagi Anda untuk memulai.

Operator Perbandingan

Dan sekali lagi kita ingat matematika. Tanda-tandanya sudah tidak asing lagi bagi semua orang. Dalam pemrograman mereka disebut operator perbandingan. JavaScript menggunakan operator perbandingan berikut:

< меньше
> lebih lanjut
<= меньше или равно
>= lebih besar atau sama dengan
== sama
!= tidak sama
=== benar-benar sama
!== sama sekali tidak sama

Perlu diketahui bahwa tanda “lebih besar dari atau sama dengan” ditulis persis seperti ini >= , bukan => . Artinya, panah ditempatkan sebelum tanda sama dengan, bukan setelahnya.

Operator perbandingan memungkinkan Anda membandingkan nilai variabel dan hasil operasi ini selalu berupa nilai Boolean benar atau salah. Mereka biasanya digunakan dalam ekspresi kondisional. Hasil perbandingan menentukan bagian kode mana yang akan dieksekusi selanjutnya.

Dalam JavaScript, Anda dapat membandingkan tipe data yang berbeda secara bersamaan, misalnya angka dan string:

12345 == "12345" // benar

Hanya saja dalam hal ini string otomatis diubah menjadi angka. Persamaan ketat === atau pertidaksamaan!== hanya digunakan saat membandingkan variabel bertipe sama.

Operator logika

Operasi logika dalam JavaScript adalah salah satu topik yang agak rumit untuk pemula. Penting untuk memahaminya secara menyeluruh agar berhasil maju dalam penguasaan bahasa tersebut. Mereka paling sering digunakan bersama dengan operator perbandingan dan menghasilkan nilai Boolean true atau false .

Ada tiga operator logis:

&& (DAN)
|| (ATAU)
! (BUKAN)

Operator logika && (DAN)

Operator && melakukan operasi logika AND pada dua nilai. Namun, ia mengembalikan nilai true jika dan hanya jika kedua operan bernilai true . Jika salah satu atau kedua operan bernilai salah, maka operator akan mengembalikan nilai salah. Contoh:

2 < 3 && 4 < 5 // true
2 < 3 && 5 < 4 // false
3 < 2 && 5 < 4 // false

Operator logika memiliki prioritas lebih rendah dibandingkan operator pembanding, jadi dalam contoh yang diberikan, kita tidak menggunakan tanda kurung. Jelas bahwa pertama-tama kita membandingkan angka satu sama lain, dan baru kemudian menerapkan logika.

Operator logika || (ATAU)

Dengan operator logika || (ATAU) lagu lain. Operator || melakukan operasi logika OR pada dua operan. Jika salah satu atau kedua operan benar, maka hasilnya benar. Jika kedua operan salah, maka hasilnya salah. Contoh:

2 < 3 || 4 < 5 // true
2 < 3 || 5 < 4 // true
3 < 2 || 5 < 4 // false

Operator logika punya triknya. Mereka tidak menyukai pekerjaan ekstra. Omong-omong, seperti halnya saya. Mereka selalu memulai perhitungannya dari kiri ke kanan. Dan jika bagian pertama dari ekspresi tersebut cocok dengan kondisinya, maka mereka bahkan tidak mengevaluasi ekspresi lainnya.

Misalnya jika operator || menemukan nilai sebenarnya di awal, langsung memberikan nilai sebenarnya, dan tidak memeriksa sisanya. Juga, operator &&, jika menemukan ekspresi yang salah di awal, maka segera memberikan hasil yang salah, dan tidak memeriksa ekspresi lainnya.

Dan satu trik lagi: operator AND && lebih diutamakan daripada OR || jadi itu dijalankan lebih awal:

2 < 3 || 4 < 5 && 5 < 6 // здесь сначала будет выполнено вычисление в правой части, а потом уже в левой

Operator logis! (BUKAN)

Operator logis! singkatan dari "logis TIDAK". Ini digunakan hanya dengan satu operan dan membalikkan nilai operan tersebut. Jika n benar, maka!n salah. Karena operator ini hanya dapat dilampirkan ke satu operan, untuk membalikkan seluruh ekspresi, operator ini harus ditempatkan dalam tanda kurung!(n && m) .

Operator string

Kita sudah membicarakan tentang operator string sebelumnya. Ini adalah plus + yang sama yang digunakan untuk menghubungkan variabel string, atau sebaliknya - untuk rangkaian(penambahan string). Contoh:

"Igor" + "Quentor" == "Igor Quentor"

Perhatikan bahwa kata pertama diberi spasi sebelum tanda kutip penutup. Jika Anda tidak menambahkannya, baris-baris tersebut akan bergabung menjadi satu kata “IgorQuentor”.

Operator ini memiliki satu fitur: jika ekspresi berisi setidaknya satu string, maka ekspresi tersebut dan semua argumen lainnya akan diubah menjadi tipe string. Misalnya:

Operator aritmatika lainnya hanya bekerja dengan angka dan selalu mereduksi argumennya menjadi angka.

Pernyataan bersyarat

Dalam JavaScript ada dua operator kondisional if dan?: Meskipun, tepatnya, if sebenarnya merupakan instruksi kontrol dan cukup ekstensif, dengan banyak fitur dan fitur menarik. Oleh karena itu, akan ada artikel tersendiri yang membahasnya. Untuk saat ini, mari kita lihat operator kondisional yang lebih sederhana?:

Biasanya operator ini ditulis sebagai?: Namun dalam program tampilannya berbeda. Ini memiliki tiga operan. Apakah operan pertama mendahului karakter? , yang kedua ada di antara karakter? dan: ketiga - setelah:

kondisi? nilai 1: nilai 2

Arti pengoperasiannya sederhana: jika kondisi yang ditetapkan terpenuhi, maka nilai 1 dikembalikan, tetapi jika tidak, nilai 2. Operator kondisi ini sering kali berfungsi sebagai pengganti yang lebih sederhana untuk pernyataan if, ketika pernyataan if tidak terlalu penting. diperlukan. Pada saat yang sama, catatan itu sendiri dipersingkat dan lebih mudah dibaca.

Itu saja untuk saat ini!

Saya harap Anda sekarang mengerti sedikit tentang operator di JavaScript. Dan agar otak Anda tidak mendidih, berikut kartun pendek untuk Anda bersantai - Seorang programmer bisa melakukan apa saja! :)

Jika Anda baru mengenal JavaScript, jargon seperti "modle bundlers vs. module loader", "Webpack vs. Browserify", dan "AMD vs. CommonJS" dapat membingungkan.

Sistem modul JavaScript mungkin menakutkan, tetapi memahaminya sangat penting bagi pengembang.

Pada artikel ini saya akan mencoba menjelaskan semuanya dengan kata-kata sederhana (dengan beberapa contoh kode). Saya harap artikel ini bermanfaat bagi Anda.

Catatan: Untuk memudahkan, artikel akan dibagi menjadi dua bagian. Pada bagian pertama, kita akan melihat apa itu modul dan mengapa kita menggunakannya. Di Bagian 2, kita akan melihat berbagai cara untuk menggabungkan modul menjadi satu kesatuan yang kohesif.

Adakah yang bisa menjelaskan lagi apa itu modul?

Sama seperti bab buku, modul hanyalah kumpulan kata (atau kode, tergantung kasusnya).

Modul yang baik memiliki fungsionalitas tersendiri sehingga dapat ditambahkan, dipindahkan, atau dihapus sesuai kebutuhan tanpa merusak keseluruhan sistem.

Mengapa menggunakan modul?

Faktanya, modul memiliki banyak keunggulan. Yang paling penting menurut saya adalah sebagai berikut:

  1. Pemeliharaan: Menurut definisinya, sebuah modul bersifat mandiri. Modul yang dirancang dengan baik bertujuan untuk mengurangi ketergantungan bagian-bagian basis kode Anda sebanyak mungkin sehingga dapat tumbuh dan berkembang secara independen satu sama lain. Memperbarui satu modul jauh lebih mudah jika modul tersebut dipisahkan dari bagian kode lainnya. Kembali ke buku kita, misalnya, jika Anda ingin membuat perubahan kecil di satu bab dan itu memerlukan perubahan pada beberapa bagian lain di buku Anda, lakukanlah. akan menjadi mimpi buruk. Oleh karena itu, bab tersebut perlu ditulis sedemikian rupa sehingga pada saat dilakukan penyuntingan tidak mempengaruhi bab lainnya.
  2. Ruang nama: Dalam JavaScript, variabel yang berada di luar fungsi tingkat atas dianggap global (semua orang dapat mengaksesnya). Oleh karena itu, “polusi namespace” sangat umum terjadi, di mana kode yang sama sekali tidak terkait dihubungkan oleh variabel global. Berbagi variabel global dalam kode yang tidak terkait satu sama lain sangat buruk dalam pengembangan hindari mencemari namespace global dengan membuat ruang pribadi untuk variabel kita.
  3. Dapat digunakan kembali: Mari jujur. Kita semua menyalin kode ke dalam proyek baru yang telah kita tulis sebelumnya. Misalnya, bayangkan Anda menyalin beberapa metode pembantu dari proyek sebelumnya ke proyek baru. Oke, tetapi jika Anda menemukan cara terbaik untuk menulis bagian ini, Anda harus mengingat semua tempat di mana kode ini muncul untuk memperbaruinya. itu. Ini jelas membuang-buang waktu. Akan lebih mudah untuk menulis modul dan menggunakannya kembali berulang kali.

Bagaimana modul dapat diintegrasikan?

Ada banyak cara untuk mengintegrasikan modul ke dalam program Anda. Mari kita lihat beberapa di antaranya:

Pola "Modul"

Pola Modul digunakan untuk meniru konsep kelas (karena JavaScript tidak mendukung kelas secara asli), sehingga kita dapat menyimpan metode (variabel) publik dan pribadi di dalam satu objek, seperti kelas dalam bahasa lain seperti Java atau Python . Hal ini memungkinkan kita untuk membuat API publik dan menyediakan kemampuan untuk mengakses metode publik, sementara variabel dan metode privat diringkas dalam penutupan.

Ada beberapa cara untuk mengimplementasikan pola Modul. Pada contoh pertama saya akan menggunakan penutupan anonim. Menempatkan kode dalam fungsi anonim akan membantu kita mencapai tujuan kita. (Ingat bahwa dalam JavaScript, fungsi adalah satu-satunya cara untuk membuat cakupan baru).

Contoh 1: Penutupan Anonim

(function () ( // Kami menjaga privasi variabel-variabel ini di dalam cakupan penutupan ini var myGrades = ; var average = function() ( var total = myGrades.reduce(function(accumulator, item) ( return accumulator + item), 0); return "Nilai rata-rata Anda adalah " + total / myGrades.length + " ) var failed = function())( var failedGrades = myGrades.filter(function(item) ( kembalikan item< 70;}); return "You failed " + failingGrades.length + " times."; } console.log(failing()); }());

Dengan cara ini, fungsi anonim kami memiliki cakupan atau “penutupan” sendiri dan kami dapat segera menjalankannya. Metode ini memungkinkan kita menyembunyikan variabel dari lingkup induk (global).

Hal yang menarik dari pendekatan ini adalah Anda dapat menggunakan variabel lokal di dalam fungsi ini dan tidak takut akan menimpa variabel global dengan nama yang sama secara tidak sengaja. Namun Anda masih memiliki akses ke variabel global, misalnya seperti ini:

Var global = "Halo, saya adalah variabel global :)"; (function () ( // Kami menjaga privasi variabel-variabel ini di dalam cakupan penutupan ini var myGrades = ; var average = function() ( var total = myGrades.reduce(function(accumulator, item) ( return accumulator + item), 0); return "Nilai rata-rata Anda adalah " + total / myGrades.length + " ) var failed = function())( var failedGrades = myGrades.filter(function(item) ( kembalikan item< 70;}); return "You failed " + failingGrades.length + " times."; } console.log(failing()); console.log(global); }()); // "You failed 2 times." // "Hello, I am a global variable:)"

Contoh 2: Impor Global

Pendekatan populer lainnya yang digunakan perpustakaan seperti jQuery adalah impor global. Ini mirip dengan penutupan yang baru saja kita lihat, hanya saja sekarang kita meneruskan variabel global sebagai parameter.

(function (globalVariable) ( // Jaga kerahasiaan variabel ini di dalam cakupan penutupan ini var privateFunction = function() ( console.log("Ssst, ini pribadi!"); ) // Tampilkan metode di bawah melalui antarmuka globalVariable sementara / / menyembunyikan implementasi metode di dalam blok // function() globalVariable.each = function(collection, iterator) ( if (Array.isArray(collection)) ( for (var i = 0; i< collection.length; i++) { iterator(collection[i], i, collection); } } else { for (var key in collection) { iterator(collection, key, collection); } } }; globalVariable.filter = function(collection, test) { var filtered = ; globalVariable.each(collection, function(item) { if (test(item)) { filtered.push(item); } }); return filtered; }; globalVariable.map = function(collection, iterator) { var mapped = ; globalUtils.each(collection, function(value, key, collection) { mapped.push(iterator(value)); }); return mapped; }; globalVariable.reduce = function(collection, iterator, accumulator) { var startingValueMissing = accumulator === undefined; globalVariable.each(collection, function(item) { if(startingValueMissing) { accumulator = item; startingValueMissing = false; } else { accumulator = iterator(accumulator, item); } }); return accumulator; }; }(globalVariable));

Dalam contoh ini, GlobalVariable adalah satu-satunya variabel global. Keuntungan dari pendekatan ini adalah Anda mendeklarasikan semua variabel global terlebih dahulu, yang membuat kode Anda transparan bagi orang lain.

Contoh 3: Antarmuka Objek

Pendekatan lain untuk membuat modul adalah dengan menggunakan antarmuka berbasis objek yang berdiri sendiri, seperti ini:

Var myGradesCalculate = (function () ( // Jaga kerahasiaan variabel ini di dalam cakupan penutupan ini var myGrades = ; // Tampilkan fungsi-fungsi ini melalui antarmuka sambil bersembunyi // implementasi modul di dalam blok function() return ( rata-rata: fungsi () ( var total = myGrades.reduce(function(accumulator, item) ( return accumulator + item; ), 0); return"Nilai rata-rata Anda adalah " + total / myGrades.length + "."; ), gagal: fungsi () ( var failedGrades = myGrades.filter(fungsi(item) ( mengembalikan item< 70; }); return "You failed " + failingGrades.length + " times."; } } })(); myGradesCalculate.failing(); // "You failed 2 times." myGradesCalculate.average(); // "Your average grade is 70.33333333333333."

Seperti yang mungkin Anda ketahui, pendekatan ini memungkinkan kita memutuskan variabel (metode) mana yang ingin kita jadikan pribadi (misalnya, nilai saya ), dan mana yang bersifat publik dengan menempatkannya di objek yang dikembalikan (misalnya, rata-rata Dan kegagalan ).

Contoh 4: Pola Modul Drop-Down

Contoh ini sangat mirip dengan contoh sebelumnya, hanya saja semua metode dan variabel tetap bersifat pribadi sampai terungkap secara eksplisit.

Var myGradesCalculate = (function () ( // Jaga kerahasiaan variabel ini di dalam cakupan penutupan ini var myGrades = ; var average = function() ( var total = myGrades.reduce(function(accumulator, item) ( return accumulator + item; ), 0); return"Nilai rata-rata Anda adalah " + total / myGrades.length + "." var failed = function() ( var failedGrades = myGrades.filter(function(item) ( kembalikan item< 70; }); return "You failed " + failingGrades.length + " times."; }; // Explicitly reveal public pointers to the private functions // that we want to reveal publicly return { average: average, failing: failing } })(); myGradesCalculate.failing(); // "You failed 2 times." myGradesCalculate.average(); // "Your average grade is 70.33333333333333."

Ini mungkin tampak seperti informasi yang banyak, tetapi ini hanyalah puncak gunung es dalam hal pola modul. Berikut adalah beberapa sumber berguna yang saya temukan dalam penelitian saya:

  • oleh Addy Osmani: ini adalah harta karun berupa detail dan konten singkat yang mengesankan;
  • Cukup Baik oleh Ben Cherry: gambaran umum yang berguna dengan contoh penggunaan pola Modul tingkat lanjut;
  • Blog Carl Danley: ikhtisar pola Modul dan sumber daya untuk pola JavaScript lainnya;

CommonJS dan AMD

Semua pendekatan yang tercantum di atas memiliki satu kesamaan: semuanya membuat satu variabel global tempat mereka menempatkan kode fungsi, sehingga menciptakan namespace pribadi dan menggunakan cakupan penutupan.

Meskipun masing-masing pendekatan ini efektif dengan caranya masing-masing, pendekatan tersebut juga memiliki kelemahan.

Sebagai pengembang, Anda perlu mengetahui urutan yang benar dalam memuat file. Misalnya, Anda menggunakan Backbone dalam proyek Anda, jadi Anda menyertakan skrip Backbone melalui tag di file Anda. Karena Backbone secara langsung bergantung pada Underscore.js, Anda tidak dapat menyertakan skrip Backbone.js sebelum Underscore.js.

Mengelola dependensi sebagai pengembang terkadang bisa memusingkan.

Kerugian lainnya adalah konflik namespace masih bisa terjadi. Misalnya, Anda mungkin memiliki dua modul dengan nama yang sama, atau dua versi dari modul yang sama, dan Anda memerlukan keduanya.

Hal ini menimbulkan pertanyaan menarik: bisakah kita mengakses antarmuka modul tidak melalui lingkup global?

Untungnya, jawabannya adalah ya.

Ada dua pendekatan yang populer dan diterapkan dengan baik: CommonJS dan AMD.

JS Umum

CommonJS adalah kelompok sukarelawan pengembang yang merancang dan mengimplementasikan API JavaScript untuk mendeklarasikan modul.

Modul CommonJS adalah bagian kode JavaScript yang dirancang untuk digunakan kembali. Ini mengekspor objek khusus, membuatnya tersedia untuk modul lain sehingga mereka dapat memasukkannya ke dalam dependensinya. Jika Anda pernah memprogram di Node.js, ini pasti sudah tidak asing lagi bagi Anda.

Dengan CommonJS, setiap file JavaScript menyimpan modul dalam konteks uniknya sendiri (seperti penutupan). Di ruang ini kita menggunakan objek modul.ekspor untuk mengekspor modul, dan memerlukan untuk menghubungkannya.

Definisi modul CommonJS mungkin terlihat seperti ini:

Fungsi myModule() ( this.hello = function() ( return "halo!"; ) this.goodbye = function() ( return "goodbye!"; ) ) module.exports = myModule;

Kami menggunakan objek khusus modul dan letakkan tautan ke fungsi kami di modul.ekspor . Hal ini memungkinkan CommonJS mengetahui bahwa kita ingin membuka modul sehingga file lain dapat menggunakannya.

Setelah itu, ketika seseorang ingin menggunakan milik kita modul saya, dia akan dapat menghubungkannya tanpa masalah sebagai berikut:

Var myModule = memerlukan("myModule"); var myModuleInstance = myModule baru(); myModuleInstance.halo(); // "Halo!" myModuleInstance.selamat tinggal(); // "selamat tinggal!"

Pendekatan ini memiliki dua keuntungan nyata dibandingkan pendekatan yang kita bahas sebelumnya:

  1. Tidak ada polusi namespace global;
  2. Menjadikan ketergantungan kita lebih eksplisit;

Selain itu, sintaksnya sangat ringkas, saya sangat menyukainya.

Perlu dicatat bahwa CommonJS menggunakan server-pertama pendekatan dan modul dimuat secara serempak. Hal ini penting karena jika kita memiliki tiga modul lagi yang perlu dihubungkan, modul tersebut akan dimuat satu demi satu.

Ini berfungsi dengan baik di server sekarang, tapi sayangnya ini membuat penulisan JavaScript berbasis browser menjadi sulit. Mengambil modul dari Internet membutuhkan waktu lebih lama dibandingkan mengambil modul dari hard drive. Saat skrip memuat modul, browser diblokir dan Anda tidak dapat melakukan apa pun hingga modul selesai dimuat. Ini berperilaku seperti ini karena thread JavaScript dihentikan ketika kode sedang dimuat (Saya akan memberi tahu Anda bagaimana kita dapat mengatasi masalah ini di bagian kedua artikel, ketika kita melihat pembuatan modul . Untuk saat ini, hanya itu yang perlu kami ketahui.)

AMD

CommonJS bagus, tetapi bagaimana jika kita perlu memuat modul secara asinkron? Jawaban atas pertanyaan ini adalah “Definisi Modul Asynchronous” atau sederhananya AMD.

Define(["myModule", "myOtherModule"], function(myModule, myOtherModule) ( console.log(myModule.hello()); ));

Fungsi definisi modul mengambil array dependensi sebagai argumen pertamanya. Dependensi ini dimuat secara latar belakang (non-pemblokiran) dan memanggil fungsi panggilan balik yang diteruskan sebagai argumen kedua.

Selanjutnya, fungsi panggilan balik mengambil dependensi yang sudah dimuat sebagai argumen dan memungkinkan Anda menggunakannya. Terakhir, dependensinya sendiri juga harus didefinisikan menggunakan kata kunci mendefinisikan .

Misalnya, modul saya mungkin terlihat seperti ini:

Define(, function() ( return ( hello: function() ( console.log("hello"); ), selamat tinggal: function() ( console.log("goodbye"); ) ); ));

Jadi mari kita ulangi lagi. Tidak seperti CommonJS, AMD menerapkan pendekatan yang mengutamakan browser bersama dengan perilaku asinkron (Perhatikan bahwa cukup banyak orang yang mengklaim bahwa pemuatan file dinamis tidak bermanfaat bagi eksekusi kode Anda. Kami akan membicarakan hal ini lebih lanjut di bagian selanjutnya dari artikel kami pada modul bangunan).

Selain asinkron, AMD punya keunggulan lain. Modul AMD dapat berupa fungsi, konstruktor, string, JSON dan tipe lainnya, sedangkan CommonJS hanya mendukung objek sebagai modul.

Pada sisi negatifnya, AMD tidak kompatibel dengan io, sistem file, dan fitur-fitur server-sentris lainnya yang tersedia melalui CommonJS. Dan sintaksis fungsi deklarasi modul bertele-tele dibandingkan dengan yang sederhana memerlukan .

UMD

Untuk proyek yang memerlukan dukungan untuk fitur AMD dan CommonJS, ada format lain. Definisi Modul Universal, atau sederhananya UMD.

Pada dasarnya, UMD menyediakan kemampuan untuk menggunakan salah satu dari dua metode di atas, ditambah lagi mendukung pendefinisian modul melalui variabel global. Hasilnya, modul UMD dapat berjalan di klien dan server.

Contoh singkat cara kerja UMD:

(fungsi (root, pabrik) ( if (typeof mendefinisikan === "fungsi" && mendefinisikan.amd) ( // AMD mendefinisikan(["myModule", "myOtherModule"], pabrik); ) else if (typeof ekspor == = "objek") ( // CommonJS module.exports = factory(require("myModule"), require("myOtherModule")); ) else ( // Browser global (Catatan: root adalah jendela) root.returnExports = pabrik( root.myModule, root.myOtherModule); ) )(ini, fungsi (myModule, myOtherModule) ( // Fungsi metode notHelloOrGoodbye())(); // Fungsi metode privat hello())(); karena "dikembalikan (lihat di bawah) fungsi selamat tinggal())(; // Metode publik karena" dikembalikan (lihat di bawah) // Metode publik terbuka kembali ( halo: halo, selamat tinggal: selamat tinggal )));

JS asli

Fiuh. Apakah kamu masih ada? Apa aku kehilanganmu di hutan ini? Bagus! Karena kami memiliki jenis definisi modul yang lain.

Seperti yang mungkin Anda ketahui di atas, tidak ada satu pun modul yang merupakan JavaScript asli. Sebagai gantinya, kami mensimulasikan sistem modul menggunakan pola Modul, CommonJS, atau AMD.

Untungnya, orang-orang pintar di TC39 (badan standar yang mendefinisikan sintaksis dan semantik ECMAScript) menambahkan modul bawaan ke ECMAScript 6 (ES6).

ES6 menawarkan berbagai pilihan untuk mengimpor dan mengekspor modul, yang telah dibahas lebih dari satu kali. Berikut adalah beberapa sumber:

  • jsmodules.io
  • menjelajahijs.com

Apa kelebihan modul ES6 dibandingkan CommonJS dan AMD? Bahwa ia menyatukan yang terbaik dari kedua dunia: kekompakan, sintaksis deklaratif, pemuatan asinkron, ditambah manfaat tambahan seperti ketergantungan melingkar.

Mungkin fitur favorit saya dari modul ES6 adalah bahwa impor bersifat langsung, jenis ekspor hanya-baca (dibandingkan dengan CommonJS, di mana impor hanyalah salinan dari ekspor).

Berikut ini contoh cara kerjanya:

// lib/counter.js var counter = 1; fungsi kenaikan() ( penghitung++; ) fungsi penurunan() ( penghitung--; ) module.exports = ( penghitung: penghitung, kenaikan: kenaikan, penurunan: penurunan ); // src/main.js var counter = memerlukan("../../lib/counter"); counter.kenaikan(); console.log(counter.counter); // 1

Dalam contoh ini, kami membuat dua salinan modul dasar: pertama kali saat kami mengekspornya, dan kedua kali saat kami mengimpornya.

Selain itu, salinan yang ada di main.js sekarang terputus dari modul aslinya. Jadi meskipun kita menambah penghitung, ia tetap mengembalikan 1 karena menangkal- ini adalah variabel yang kami impor dari modul, terputus dari modul aslinya.

Jadi meningkatkan penghitung akan menambahnya dalam modul, tetapi tidak akan menambahnya dalam versi yang disalin. Satu-satunya cara untuk mengubah versi yang disalin adalah dengan menambahkannya secara manual:

Counter.counter++; console.log(counter.counter); // 2

Dan, ES6, saat mengimpor, membuat tampilan modul hanya-baca langsung:

// lib/counter.js ekspor biarkan counter = 1; fungsi ekspor kenaikan() ( counter++; ) fungsi ekspor penurunan() ( counter--; ) // src/main.js impor * sebagai penghitung dari "../../counter"; console.log(counter.counter); // 1 counter.kenaikan(); console.log(counter.counter); // 2

Menarik bukan? Apa yang menurut saya sangat menarik tentang tampilan live read-only adalah bahwa mereka memungkinkan Anda membagi modul menjadi bagian-bagian yang lebih kecil tanpa kehilangan fungsionalitas.

Anda dapat menerapkan dan menggabungkannya lagi (dalam proyek baru) dan tidak ada masalah. Semuanya akan berhasil.

Sedikit ke depan: Merakit modul

Wow! Betapa cepatnya waktu berlalu. Ini merupakan perjalanan yang luar biasa dan saya sangat berharap artikel ini dapat memberi Anda pemahaman yang lebih baik tentang modul dalam JavaScript.

Pada artikel berikutnya, kita akan melihat pengikatan modul, yang mencakup topik-topik utama termasuk:

  • Mengapa kami mengumpulkan modul;
  • Pendekatan berbeda untuk perakitan;
  • API pemuat modul ECMAScript;
  • Dan masih banyak lagi...

Bertanggung jawab atas operasi matematika. Pada artikel ini kita akan melihat konstanta dan metode kelas ini, serta mempelajari cara menggunakannya dalam proses pemrograman yang sulit.

Mari kita mulai dengan konstanta Objek matematika. Mari kita pertimbangkan konstanta E Dan hal.i.(diketahui oleh Anda dari matematika). Ayo segera cetak:

Dokumen.write(Matematika.E);
dokumen.tulis("
");
dokumen.write(Matematika.PI);

Jika Anda menjalankan skrip ini, Anda akan melihat nilai dari dua konstanta paling populer dalam matematika.

Sekarang mari kita beralih ke metodenya. Objek matematika dalam JavaScript. Cara yang pertama adalah perut(x), yang mengambil angka sebagai parameter dan mengembalikan modulusnya. Misalnya seperti ini:

Var x = -15,2;
dokumen.tulis(Matematika.abs(x));

Hasilnya adalah angka " 15.2 ".

Metode selanjutnya adalah acak(). Metode yang sangat populer yang menghasilkan angka secara acak dari 0 hingga 1. Lebih-lebih lagi, 0 masuk dan 1 tidak lagi disertakan. Mari kita dapatkan nomornya dari 0 hingga 10.

Dokumen.tulis(Matematika.acak() * 10);

Baris ini akan menampilkan nomor tersebut dari 0 hingga 10(dan pecahan). perhatikan itu 0 mungkin, tapi 10 Tidak mungkin.

metode persegi(x) menghitung akar kuadrat suatu bilangan. Penerapannya jelas dan sangat sederhana:

Dokumen.tulis(Matematika.sqrt(9));

Dalam contoh ini, setelah menjalankan skrip kita akan melihat nomor " 3 ".

metode catatan(x) menghitung logaritma natural suatu bilangan.

Dokumen.tulis(Math.log(Math.E * Math.E));

Tentu saja jawabannya adalah " 2 ".

Metode lain menghitung pangkat suatu bilangan. Metode ini disebut - kekuatan(x, y). Mengambil dua parameter, yang pertama adalah basis bilangan, dan yang kedua adalah pangkatnya. Sekadar contoh:

Dokumen.tulis(Matematika.pow(2, 5));

Sangat logis bahwa hal itu akan terjadi 32 .

Dan terakhir, mari kita pertimbangkan sekelompok metode yang menjalankan fungsi trigonometri:

Var x = 0,1;
dokumen.tulis(Matematika.sin(x) + "
"); // Sinus bilangan
dokumen.tulis(Matematika.cos(x) + "
"); //Kosinus suatu bilangan
dokumen.tulis(Matematika.tan(x) + "
"); // Garis singgung suatu bilangan
dokumen.tulis(Matematika.asin(x) + "
"); // Arcsinus dari bilangan tersebut
dokumen.tulis(Matematika.acos(x) + "
"); //Arc cosinus suatu bilangan
dokumen.tulis(Matematika.atan(x) + "
"); //Arctangent dari bilangan tersebut.

Untuk mencegah penggabungan hasil eksekusi fungsi trigonometri, setiap akhir eksekusi dilakukan transisi ke baris baru (
).