Mode ketat adalah bagian penting dari JavaScript modern. Mode ini yang memungkinkan pengembang untuk menggunakan lebih terbatas daripada sintaksis standar.
Semantik mode ketat berbeda dari mode non-ketat tradisional, yang kadang-kadang disebut "mode ceroboh". Dalam mode ini, aturan sintaks bahasa tidak begitu ketat, dan ketika beberapa kesalahan terjadi, sistem tidak memberi tahu pengguna tentang mereka. Yaitu, kesalahan dapat diabaikan, dan kode di mana mereka dibuat dapat dieksekusi lebih lanjut. Ini dapat menyebabkan hasil eksekusi kode yang tidak terduga.

Mode ketat memperkenalkan beberapa perubahan pada semantik JavaScript. Ini mencegah sistem dari menutup mata terhadap kesalahan dengan melemparkan pengecualian yang sesuai. Ini menyebabkan eksekusi program terhenti.
Mode ketat, di samping itu, membantu dalam menulis program di mana tidak ada kekurangan yang mencegah mesin JS dari mengoptimalkan kode. Lebih lanjut, dalam mode ini dilarang menggunakan elemen sintaks yang mungkin mendapatkan makna khusus dalam versi bahasa yang akan datang.
Fitur menggunakan mode ketat
Mode ketat dapat diterapkan ke fungsi individual atau ke seluruh skrip. Itu tidak bisa diterapkan hanya pada instruksi individual atau pada blok kode yang dilampirkan dalam kurung kurawal. Untuk menggunakan mode ketat di tingkat keseluruhan skrip, di bagian paling awal file, sebelum perintah lain, Anda harus
"use strict"
atau
'use strict'
konstruksi
'use strict'
.
Jika proyek memiliki beberapa skrip yang tidak menggunakan mode ketat, dan lain-lain yang menggunakan mode ini, maka mungkin saja skrip ini digabungkan.
Ini akan mengarah pada fakta bahwa kode yang tidak dimaksudkan untuk dieksekusi dalam mode ketat akan berada dalam keadaan seperti itu ketika sistem mencoba untuk mengeksekusinya dalam mode ketat. Kebalikannya juga dimungkinkan - kode yang ditulis untuk mode ketat akan jatuh ke mode non-ketat. Karena itu, yang terbaik adalah tidak mencampur skrip "ketat" dan "tidak ketat".
Seperti yang telah disebutkan, mode ketat dapat diterapkan ke fungsi individual. Untuk melakukan ini - konstruksi
"use strict"
atau
'use strict'
harus ditempatkan di bagian atas tubuh fungsi, sebelum perintah lainnya. Mode ketat dengan pendekatan ini berlaku untuk semua yang ditempatkan di tubuh fungsi, termasuk fungsi bersarang.
Sebagai contoh:
const strictFunction = ()=>{ 'use strict'; const nestedFunction = ()=>{
Dalam modul JavaScript yang muncul dalam standar ES2015, mode ketat diaktifkan secara default. Karena itu, ketika bekerja dengan mereka, Anda tidak perlu memasukkannya secara eksplisit.
Perubahan yang diperkenalkan ke kode JS dengan mode ketat
Mode ketat memengaruhi sintaksis kode dan cara kode berperilaku selama eksekusi program. Kesalahan dalam kode dikonversi menjadi pengecualian. Fakta bahwa dalam mode diam diam-diam crash dalam mode ketat menyebabkan pesan kesalahan. Ini mirip dengan bagaimana sistem merespons kesalahan sintaks dalam mode lax. Dalam mode ketat, bekerja dengan variabel disederhanakan, penggunaan fungsi
eval
dan objek
arguments
diatur dengan ketat, dan bekerja dengan konstruksi yang dapat diimplementasikan dalam versi bahasa yang akan datang disederhanakan.
โ Konversi kesalahan diam menjadi pengecualian
Kesalahan diam dikonversi dalam mode ketat ke pengecualian. Dalam mode longgar, sistem tidak secara eksplisit merespons kesalahan tersebut. Dalam mode ketat, keberadaan kesalahan seperti itu menyebabkan kode tidak dapat dioperasikan.
Jadi, berkat ini, sulit untuk membuat kesalahan dengan secara tidak sengaja mendeklarasikan variabel global, karena variabel dan konstanta dalam mode ketat tidak dapat dideklarasikan tanpa menggunakan arahan
var
,
let
atau
const
. Akibatnya, membuat variabel tanpa arahan ini akan menyebabkan program tidak dapat dioperasikan. Misalnya, mencoba untuk mengeksekusi kode berikut akan memunculkan exception
ReferenceError
:
'use strict'; badVariable = 1;
Kode tersebut tidak dapat dijalankan dalam mode ketat, karena jika mode ketat dimatikan, itu akan membuat variabel global
badVariable
. Mode ketat melindungi programmer dari membuat variabel global secara tidak sengaja.
Upaya untuk mengeksekusi kode apa pun yang, dalam mode normal, tidak berfungsi, sekarang melempar pengecualian. Kesalahan dianggap sebagai konstruksi sintaksis yang salah yang diabaikan begitu saja dalam mode longgar.
Jadi, misalnya, dalam mode ketat, Anda tidak bisa melakukan operasi penetapan nilai pada entitas read-only seperti
arguments
,
NaN
atau
eval
.
Dalam mode ketat, pengecualian, misalnya, akan dilemparkan dalam kasus berikut:
- upaya untuk menetapkan nilai ke properti hanya-baca, seperti beberapa jenis properti global yang dapat ditulis ulang;
- upaya untuk menulis nilai ke properti yang hanya memiliki pengambil;
- Upaya untuk menulis sesuatu ke properti objek yang tidak dapat diperluas.
Berikut adalah contoh konstruksi sintaks yang mengarah ke pengecualian mode ketat:
'use strict'; let undefined = 5; let Infinity = 5; let obj = {}; Object.defineProperty(obj, 'foo', { value: 1, writable: false }); obj.foo = 1 let obj2 = { get foo() { return 17; } }; obj2.foo = 2 let fixedObj = {}; Object.preventExtensions(fixedObj); fixed.bar= 1;
Mencoba menjalankan fragmen kode tersebut dalam mode ketat akan menghasilkan pengecualian
TypeError
. Misalnya,
undefined
dan
Infinity
adalah entitas global yang nilainya tidak dapat ditimpa, dan properti
foo
objek
obj
tidak mendukung penulisan ulang. Properti
foo
dari
obj2
hanya memiliki pengambil. Objek
fixedObj
dibuat non-extensible menggunakan metode
Object.preventExtensions
.
Upaya menghapus
TypeError
terhapuskan juga akan menghasilkan
TypeError
:
'use strict'; delete Array.prototype
Mode ketat melarang menetapkan properti dengan nama yang sama ke objek. Akibatnya, upaya untuk mengeksekusi kode berikut akan menghasilkan kesalahan sintaksis:
'use strict'; let o = { a: 1, a: 2 };
Mode ketat membutuhkan nama parameter fungsi menjadi unik. Dalam mode non-ketat, jika, misalnya, dua parameter fungsi memiliki nama yang sama
one
, maka, ketika melewati fungsi argumen, nilai parameter akan menjadi apa yang termasuk dalam argumen yang dinyatakan terakhir.
Dalam mode ketat, parameter fungsi dengan nama yang sama dilarang. Akibatnya, upaya untuk mengeksekusi kode berikut akan menghasilkan kesalahan sintaksis:
'use strict'; const multiply = (x, x, y) => x*x*y;
Dalam mode ketat, Anda tidak dapat menggunakan notasi oktal angka, mendahului angka dengan nol. Ini tidak ada dalam spesifikasi, tetapi fitur ini didukung oleh browser.
Keadaan ini membingungkan pengembang, memaksa mereka untuk percaya bahwa angka 0 sebelumnya diabaikan, tanpa banyak akal. Dalam mode ketat, mencoba menggunakan angka di awal yang 0 akan menghasilkan kesalahan sintaks.
Mode ketat juga melarang penggunaan konstruksi yang menghambat optimasi. Penerjemah, sebelum melakukan optimasi kode, perlu tahu bahwa variabel disimpan tepat di mana, menurut penerjemah, itu disimpan. Dalam mode ketat, hal-hal yang mengganggu optimasi dilarang.
Salah satu contoh larangan semacam itu menyangkut pernyataan
with
. Jika Anda menggunakan instruksi ini, ini mencegah penerjemah JS dari menemukan variabel atau properti mana yang kami maksudkan, karena ada kemungkinan bahwa entitas dengan nama yang sama ada di luar dan di dalam blok pernyataan
with
.
Misalkan ada kode seperti ini:
let x = 1; with (obj) { x; }
Penerjemah tidak akan dapat mengetahui apakah variabel
x
terletak di dalam blok
with
mengacu pada variabel eksternal
x
, atau ke properti
obj.x
dari objek
obj
.
Akibatnya, tidak jelas persis di mana nilai
x
akan berada di memori. Untuk menghilangkan ambiguitas seperti itu, dalam mode ketat penggunaan pernyataan
with
dilarang. Mari kita lihat apa yang terjadi jika Anda mencoba menjalankan kode berikut dalam mode ketat:
'use strict'; let x = 1; with (obj) { x; }
Hasil dari upaya ini akan menjadi kesalahan sintaksis.
Bahkan dalam mode ketat, dilarang untuk mendeklarasikan variabel dalam kode yang diteruskan ke metode
eval
.
Misalnya, dalam mode normal, perintah form
eval('let x')
akan menghasilkan deklarasi variabel
x
. Hal ini memungkinkan pemrogram untuk menyembunyikan deklarasi variabel dalam string, yang dapat menyebabkan menimpa definisi variabel yang sama di luar
eval
.
Untuk mencegah hal ini, dalam mode ketat dilarang untuk mendeklarasikan variabel dalam kode yang diteruskan sebagai string ke metode
eval
.
Mode ketat juga melarang penghapusan variabel reguler. Akibatnya, mencoba mengeksekusi kode berikut akan menghasilkan kesalahan sintaksis:
'use strict'; let x; delete x;
โ Melarang konstruksi sintaks yang salah
Dalam mode ketat, penggunaan yang salah dari
arguments
dan
arguments
dilarang. Ini adalah larangan semua jenis manipulasi dengan mereka. Sebagai contoh, ini adalah sesuatu seperti memberikan nilai baru kepada mereka, menggunakan nama mereka sebagai nama variabel, fungsi, parameter fungsi.
Berikut adalah contoh penyalahgunaan
eval
dan
arguments
:
'use strict'; eval = 1; arguments++; arguments--; ++eval; eval--; let obj = { set p(arguments) { } }; let eval; try { } catch (arguments) { } try { } catch (eval) { } function x(eval) { } function arguments() { } let y = function eval() { }; let eval = ()=>{ }; let f = new Function('arguments', "'use strict'; return 1;");
Dalam mode ketat, Anda tidak bisa membuat alias untuk objek
arguments
dan menetapkan nilai
arguments
baru melalui alias ini.
Dalam mode normal, jika parameter pertama dari fungsi adalah
a
, maka pengaturan nilai
a
dalam kode fungsi juga mengarah ke perubahan nilai dalam
arguments[0]
. Dalam mode ketat,
arguments
akan selalu berisi daftar argumen yang dengannya fungsi dipanggil.
Misalkan Anda memiliki kode berikut:
const fn = function(a) { 'use strict'; a = 2; return [a, arguments[0]]; } console.log(fn(1))
Konsol akan mendapatkan
[2,1]
. Ini karena menulis nilai 2 ke
a
tidak menulis nilai 2 ke
arguments[0]
.
PtOptimasi kinerja
Dalam mode ketat, properti
arguments.callee
tidak didukung. Dalam mode normal, ia mengembalikan nama fungsi induk dari fungsi yang properti
callee
dari objek
arguments
kita periksa.
Dukungan untuk properti ini mengganggu optimisasi, seperti fungsi inlining, karena menggunakan
arguments.callee
membutuhkan ketersediaan referensi ke fungsi yang tidak tertanam ketika mengakses properti ini. Dalam mode ketat, menggunakan
arguments.callee
memunculkan exception
TypeError
.
Dalam mode ketat,
this
ini tidak harus selalu menjadi objek. Dalam keadaan normal, jika fungsi ini terikat, menggunakan
call
,
apply
atau
bind
, untuk sesuatu yang bukan objek, ke nilai tipe primitif seperti
undefined
,
null
,
number
atau
boolean
, nilai seperti itu harus menjadi objek.
Jika konteks
this
berubah menjadi sesuatu yang bukan objek, objek global akan menggantikannya. Misalnya,
window
. Ini berarti bahwa jika Anda memanggil fungsi dengan mengatur
this
ke nilai yang bukan objek, bukan nilai ini, referensi ke objek global akan jatuh ke
this
.
Pertimbangkan sebuah contoh:
'use strict'; function fn() { return this; } console.log(fn() === undefined); console.log(fn.call(2) === 2); console.log(fn.apply(null) === null); console.log(fn.call(undefined) === undefined); console.log(fn.bind(true)() === true);
Semua perintah
console.log
akan menghasilkan
true
, karena dalam mode ketat nilai
this
dalam fungsi tidak secara otomatis diganti oleh referensi ke objek global jika
this
disetel ke nilai yang bukan objek.
โ Perubahan terkait keamanan
Dalam mode ketat, Anda tidak dapat membuat properti fungsi
caller
dan
arguments
publik. Faktanya adalah
caller
, misalnya, dapat memberikan akses ke fungsi yang disebut fungsi yang properti
caller
sedang kita akses.
Objek
arguments
menyimpan argumen yang dilewatkan ke fungsi ketika dipanggil. Misalnya, jika kita memiliki fungsi
fn
, ini berarti bahwa melalui
fn.caller
Anda dapat mengakses fungsi yang disebut fungsi, dan menggunakan
fn.arguments
Anda dapat melihat argumen yang dilewatkan ke
fn
ketika dipanggil.
Fitur-fitur ini berpotensi menimbulkan risiko keamanan. Akibatnya, akses ke properti ini dilarang dalam mode ketat.
function secretFunction() { 'use strict'; secretFunction.caller; secretFunction.arguments; } function restrictedRunner() { return secretFunction(); } restrictedRunner();
Pada contoh sebelumnya, kita tidak bisa, dalam mode ketat, mengakses
secretFunction.caller
dan
secretFunction.arguments
. Faktanya adalah bahwa properti ini dapat digunakan untuk mendapatkan setumpuk panggilan fungsi. Jika Anda mencoba menjalankan kode ini, pengecualian
TypeError
akan
TypeError
.
Dalam mode ketat, pengidentifikasi yang dapat digunakan dalam versi JavaScript yang akan datang tidak dapat digunakan untuk memberi nama variabel atau properti objek. Sebagai contoh, kita berbicara tentang pengidentifikasi berikut:
implements
,
interface
,
let
,
package
,
private
,
protected
,
public
,
static
dan
yield
.
Dalam ES2015 dan dalam versi standar selanjutnya, pengidentifikasi ini menjadi kata-kata yang dicadangkan. Dan mereka tidak dapat digunakan untuk memberi nama variabel atau properti dalam mode ketat.
Ringkasan
Mode ketat adalah standar yang telah ada selama bertahun-tahun. Ia menikmati dukungan browser yang sangat luas. Masalah dengan kode mode ketat hanya dapat terjadi di browser lama, seperti Internet Explorer.
Browser modern seharusnya tidak mengalami kesulitan dengan mode JavaScript yang ketat. Akibatnya, kita dapat mengatakan bahwa mode ini harus digunakan untuk mencegah kesalahan "diam" dan untuk meningkatkan keamanan aplikasi. Kesalahan diam dikonversi menjadi pengecualian yang menghambat pelaksanaan program, dan dalam hal meningkatkan keamanan, misalnya, mekanisme mode ketat yang membatasi
eval
dan mencegah akses ke tumpukan panggilan fungsi dapat dicatat. Selain itu, penggunaan mode ketat memfasilitasi optimalisasi kode mesin JS dan memaksa programmer untuk hati-hati menangani kata-kata yang disimpan yang mungkin digunakan dalam versi JavaScript yang akan datang.
Pembaca yang budiman! Apakah Anda menggunakan mode ketat saat menulis kode JS untuk proyek Anda?
