Strict Mode in Javascript
Davron
Posted on April 25, 2022
ECMAScript 5 da joriy qilingan JavaScript'ning qat'iy rejimi(strict mode) JavaScript'ning cheklangan variantiga qo'shilish va shu bilan odatiy rejimdan voz kechish usulidir. Qat'iy rejim shunchaki kichik to'plam emas: u oddiy koddan farqli semantikaga ega. Qattiq rejimni qo'llab-quvvatlamaydigan brauzerlar qat'iy rejim kodini boshqa brauzerlardan boshqacharoq usulda ishga tushiradi, shuning uchun qat'iy rejimning tegishli jihatlarini brauzer qo'llab-quvvatlashini tekshirmasdan qat'iy rejimga tayanmang.
Qat'iy rejim oddiy JavaScript semantikasiga bir nechta o'zgarishlar kiritadi:
JavaScript-ning ba'zi bilinmas xatolarini xatolarga o'zgartirish kiritish orqali yo'qotadi.
JavaScript uchun optimallashtirishni qiyinlashtiradigan xatolarni tuzatadi: qat'iy rejim kodini ba'zan qat'iy rejim bo'lmagan bir xil koddan tezroq ishlash uchun ham ishlatiladi.
ECMAScript ning kelajakdagi versiyalarida aniqlanishi mumkin bo'lgan ba'zi sintaksislarni taqiqlaydi.
Qat'iy rejimni chaqirish.
Qat'iy rejim butun bir skriptlar yoki alohida funksiyalar uchun amal qiladi. Bu {} ichiga olingan blok statement'larga taalluqli emas; uni bunday kontekstlarga qo'llashga urinish natija bermaydi. eval
code, function
code, event handler
attributlar, setTimeout()
ga uzatilgan tekstlar va tegishli funktsiyalar butun skriptlardir va ulardagi qat'iy rejimni chaqirish kutilganidek ishlaydi.
Skriptlar uchun qat'iy rejim.
Butun bir skript uchun qat'iy rejimni ishga tushirish uchun, skriptning eng birinchi qatoriga "use strict"
yoki 'use strict'
iborasini yozing.
// butun bir skript qat'iy rejimda bo'lgan holat
'use strict';
var v = "Salom, men qat'iy rejimdagi skriptman!";
Funksiyalar uchun qat'iy rejim.
Xuddi shunday, Funksiyalar uchun qat'iy rejimni ishga tushirish uchun, funksiya tanasining eng birinchi qatoriga "use strict"
yoki 'use strict'
iborasini yozing.
function strict() {
// Funksiya darajasidagi qat'iy rejim sintaksisi
'use strict';
function nested() { return "Men ham qat'iy rejimdaman!"; }
return "Salom! Men qat'iy rejimdagi funksiyaman! " + nested();
}
function notStrict() { return "Men esa qat'iy rejimda emasman"; }
ES2015 dan boshlab qat'iy rejimda bloklar ichidagi funksiyalar ushbu blokda qamrab olinadi. ES2015 ga qadar blok darajasidagi funksiyalar qat'iy rejimda taqiqlangan edi.
Modullar uchun qat'iy rejim.
ECMAScript 2015 JavaScript modullarini va shu bilan birga qat'iy rejimga kirishning uchinchi usulini ham taqdim etdi. JavaScript modullarining butun tarkibi avtomatik ravishda qat'iy rejimda bo'ladi, uni boshlash uchun hech qanday maxsus kalit so'z kerak emas.
function strict() {
// bu modul bo'lganligi tufayli men avtomatik qat'iy rejimdaman
}
export default strict;
Classlar uchun qat'iy rejim.
ECMAScript classlarining barcha qismlari qat'iy rejim kodi bo'lib, class deklaratsiyasi va class ifodalarini o'z ichiga oladi va shu bilan birga class tanasining barcha qismlarini ham o'z ichiga oladi.
Qat'iy Rejimda Bo'ladigan O'zgarishlar.
Qat'iy rejim ham sintaksis, ham ishga tushirish usullarini o'zgartiradi. O'zgarishlar odatda quyidagi toifalarga bo'linadi: adashishni xatolarga aylantiruvchi o'zgarishlar (sintaksis xatolari yoki runtime), eval
va argument
larni soddalashtiruvchi o'zgarishlar, "xavfsiz" JavaScript kod yozishni osonlashtiruvchi va kelajakdagi ECMAScript evolyutsiyasini bashorat qilishi mumkin bo'lgan o'zgarishlar.
Adashishni Xatoga aylantirish.
Qat'iy rejim ilgari odatdagidek qabul qilingan ba'zi adashishlarni xatolarga o'zgartiradi. JavaScript yangi o'rganuvchilar uchun juda oson va ba'zida u semantikada xato bo'lishi kerak bo'lgan xato bo'lmagan operatsiyalarni beradi. Ba'zida bu darhol muammoni hal qiladi, lekin ba'zida bu yanada yomonroq muammolarni keltirib chiqaradi. Qat'iy rejim bu adashishlarni xato deb hisoblaydi, ular topiladi va tezda tuzatiladi.
Qattiq rejim ilgari qabul qilingan ba'zi xatolarni xatolarga o'zgartiradi. JavaScript yangi boshlanuvchilar uchun oson bo'lishi uchun yaratilgan va ba'zida u semantikada xato bo'lmagan xatolar bo'lishi kerak bo'lgan operatsiyalarni beradi. Ba'zida bu darhol muammoni hal qiladi, lekin ba'zida bu kelajakda yanada yomonroq muammolarni keltirib chiqaradi. Qattiq rejim bu xatolarni xato deb hisoblaydi, shunda ular topiladi va tezda tuzatiladi.
Birinchidan, qat'iy rejim tasodifiy global o'zgaruvchilarni yaratish imkonsiz. Oddiy JavaScript'da, o'zgaruvchini noto'g'ri yozish global obyektda yangi property'ni yaratadi va "ishlashda" davom etadi. Qat'iy rejimda esa global o'zgaruvchini tasodifan yaratish xatoga olib keladi:
'use strict';
// mistypeVariable deb nomlanuvchi global o'zgaruvchi yo'q deb tasavvur qiling
mistypeVariable = 17; // Bu qator ReferenceError qaytaradi chunki bu nomdagi o'zgaruvchi mavjud emas.
NaN
yozib bo'lmaydigan global o'zgaruvchidir. Oddiy kodda NaN
ga qiymat berish hech narsani anglatmaydi; dasturchi hech qanday xato qabul qilmaydi. Qat'iy rejimda NaN
ga qiymat berish istisno(exception)ni keltirib chiqaradi. Oddiy kodda shunchaki e'tibordan chetda qoladigan qiymat berishlar (yozib bo'lmaydigan global yoki property'ga qiymat berish, faqat qabul qiluvchi(getter-only) property'ga qiymat berish, kengaytirilmaydigan obyektda yangi property qo'shish) qat'iy rejimda xato qaytaradi:
'use strict';
// yozib bo'lmaydigan globalga qiymat berish
var undefined = 5; // TypeError qaytaradi
var Infinity = 5; // TypeError qaytaradi
// yozib bo'lmaydigan property'ga qiymat berish
var obj1 = {};
Object.defineProperty(obj1, 'x', { value: 42, writable: false });
obj1.x = 9; // TypeError qaytaradi
// getter-only property'ga qiymat berish
var obj2 = { get x() { return 17; } };
obj2.x = 5; // TypeError qaytaradi
// kengaytirib bo'lmaydigan obyektga yangi qiymat qo'shish
var fixed = {};
Object.preventExtensions(fixed);
fixed.newProp = 'ohai'; // TypeError qaytaradi
Qat'iy rejim o'chirib bo'lmaydigan property'larni o'chirishga urinishlar qiladi :
'use strict';
delete Object.prototype; // TypeError qaytaradi
Qat'iy rejim funksiya parametr nomlarining yagona bo'lishini talab qiladi. Oddiy kodda oxirgi takrorlangan argument avvalgi bir xil nomdagi argumentlarni yashirib qo'yadi. Avvalgi argumentlarga arguments[i] orqali murojjat qilish mumkin, shuning uchun aytish mumkinki ular to'liq yo'q bo'lib ketmagan. Shunga qaramay, bu yashirish kichik bo'lsada ma'noga ega va xohlamagan holda amalga oshirilgan bo'lishi mumkin(masalan, u xato yozishni yashirib qo'yishi mumkin), shuning uchun qat'iy rejimda argument nomlarining takrorlanishi syntax error
hisoblanadi:
function sum(a, a, c) { // !!! syntax error
'use strict';
return a + a + c; // xato!!!
}
ECMAScript5'da qat'iy rejim 0-prefiksli octal(sakkizlik) literal yoki octal sequense(sakkiztalik ketma-ketlik) taqiqlaydi. Qat'iy rejimdan tashqarida 0
bilan boshlanadigan raqam, masalan, 0644
, agar barcha raqamlar 8 dan kichik boʻlsa, sakkizlik son (0644 === 420
) sifatida talqin etiladi. Sakkizlik ketma-ketligi, masalan, "%" ga teng bo'lgan “\45”, sakkizta kengaytirilgan ASCII belgilar kodlarining raqamlari bilan belgilarni ko'rsatish uchun ishlatilishi mumkin. Qat'iy rejimda bu syntax error
. ECMAScript 2015 da sakkizlik literallar songa "0o
" prefiks qo'yish orqali bajariladi; misol uchun:
var a = 0o10; // ES2015: Octal
Yangi o'rganuvchilar ba'zan nol prefiksining semantik ma'nosi yo'qligiga ishonishadi, shuning uchun ular uni alignment moslamasi sifatida ishlatishlari mumkin - lekin bu raqamning ma'nosini o'zgartiradi! Sakkizlik uchun boshidagi nol sintaksisi kamdan-kam foydali bo'lib va va ba'zan xato tarzda ishlatilishi mumkin, shuning uchun qattiq rejim uni syntax error
'ga aylantirilgan:
'use strict';
var sum = 015 + // !!! syntax error
197 +
142;
var sumWithOctal = 0o10 + 8;
console.log(sumWithOctal); // 16
ECMAScript 2015 da qat'iy rejim primitive
qiymatlarga property o'rnatishni taqiqlaydi. Qattiq rejimsiz property o'rnatish e'tiborga olinmaydi (no-op), qattiq rejimda esa TypeError
'ga olib keladi.
(function() {
'use strict';
false.true = ''; // TypeError
(14).sailing = 'home'; // TypeError
'with'.you = 'far away'; // TypeError
})();
ECMAScript 5 qat'iy rejim kodida property nomlarini takrorlanishi SyntaxError
deb hisoblangan. computed property name
kiritilishi bilan runtime
'da nomlar takrorlanishi mumkin bo'ldi. ECMAScript 2015 bu cheklovni olib tashladi.
'use strict';
var o = { p: 1, p: 2 }; // ECMAScript 2015 ko'ra syntax error
eval
va argument
'larni soddalashtirish.
Qat'iy rejim arguments
va eval
'larning sehrini kamaytiradi. Ikkalasi ham oddiy kodda katta miqdordagi sehrli xatti-harakatni o'z ichiga oladi: bog'lanishlarni qo'shish yoki olib tashlash va bog'lanish qiymatlarini o'zgartirish uchun eval
. Qat'iy rejim eval
va arguments
kalit so'zlar sifatida ko'rib chiqishni o;zragtirmoqda, ammo to'liq tuzatishlar ECMAScript ning kelajakdagi varsiyalarida amalga oshirilishi kutilyapti.
Birinchidan, eval
va argument
nomlarini til sintaksisida bog‘lab yoki qiymat berib bo‘lmaydi. Buni amalga oshirishga urinishlarning barchasi sintaktik xatolardir:
'use strict';
eval = 17;
arguments++;
++eval;
var obj = { set p(arguments) { } };
var eval;
try { } catch (arguments) { }
function x(eval) { }
function arguments() { }
var y = function eval() { };
var f = new Function('arguments', "'use strict'; return 17;");
Ikkinchidan, qat'iy rejim kodi unda yaratilgan argumentlar
obyektlarining xususiyatlariga nom bermaydi. Birinchi argumenti arg
bo'lgan funksiya ichidagi oddiy kodda arg
arguments[0]
ni ham o'rnatadi va aksincha (argumentlar taqdim etilmagan yoki argumentlar[0] o'chirilgan bo'lsa). arguments
qat'iy rejim funktsiyalari uchun obyektlar funktsiya chaqirilganda asl argumentlarni saqlaydi. arguments[i]
tegishli nomli argumentning qiymatini kuzatmaydi va nomli argument tegishli arguments[i]
qiymatini kuzatmaydi.
function f(a) {
'use strict';
a = 42;
return [a, arguments[0]];
}
var pair = f(17);
console.assert(pair[0] === 42);
console.assert(pair[1] === 17);
Uchinchidan, arguments.callee
endi qo'llab-quvvatlanmaydi. Oddiy kodda arguments.callee
o'zini o'rab turgan funktsiyasiga ishora qiladi. Ushbu foydalanish holati xavfsiz emas! Bundan tashqari, arguments.callee
inlining funktsiyalari kabi optimallashtirishga sezilarli darajada to'sqinlik qiladi, chunki agar arguments.callee
ga kirilgan bo'lsa, inlined funksiyasiga havolani taqdim etish imkoniyati yaratilishi kerak. arguments.callee
qat'iy rejim funktsiyalari uchun o'chirib bo'lmaydigan xususiyat bo'lib, qiymat berilganda yoki olinganida xatolik keltirib chiqaradi:
'use strict';
var f = function() { return arguments.callee; };
f(); // TypeError qaytaradi
Xavfsiz Javascript.
Qat'iy rejim JavaScriptni "xavfsiz" yozishni osonlashtiradi. Ba'zi veb-saytlar endi foydalanuvchilarga JavaScript yozishning turli usullarini taqdim etadi. Brauzerlardagi JavaScript foydalanuvchining shaxsiy ma'lumotlariga kirishi mumkin, shuning uchun bunday JavaScript taqiqlangan funksiyalarga kirishni tsenzura qilish uchun ishga tushirishdan oldin qisman o'zgartirilishi kerak. JavaScriptning moslashuvchanligi sababli buni runtime
tekshiruvlarisiz amalga oshirish imkonsiz. Ba'zi til funktsiyalari shu qadar keng tarqalganki, runtime
tekshirishni amalga oshirish katta xarajatlarini talab qiladi. Bir nechta qat'iy rejim o'zgarishlari, shuningdek, foydalanuvchi tomonidan taqdim etilgan JavaScriptning qat'iy rejim kodi bo'lishini va uni ma'lum bir tarzda ishga tushirishni talab qilish, bu runtime
tekshirishga bo'lgan ehtiyojni sezilarli darajada kamaytiradi.
Birinchidan, qat'iy rejimdagi funktsiyaga berilgan this
qiymati obyekt bo'lishga majburlanmaydi. Oddiy funktsiya uchun this
har doim obyekt hisoblanadi: yoki taqdim etilgan obyekt
this
obyekti bilan chaqirilgan bo'lsa; qiymat, agar boolean
, string
yoki number
bilan chaqirilgan bo'lsa; yoki global obyekt, agar bu undefined
yoki null
bilan chaqirilsa. Avtomatik box nafaqat xarajatni, balki global obyektni brauzerlarda ko'rsatish xavfsizlik uchun xavf tug'diradi, chunki global obyekt "xavfsiz" JavaScript muhiti oldini olishi kerak bo'lgan funksiyalarga kirishni ta'minlaydi. Shunday qilib, qat'iy rejim funktsiyasi uchun belgilangan this
obyektga kiritilmaydi va agar aniqlanmagan
bo'lsa, bu undefined
bo'ladi:
'use strict';
function fun() { return this; }
console.assert(fun() === undefined);
console.assert(fun.call(2) === 2);
console.assert(fun.apply(null) === null);
console.assert(fun.call(undefined) === undefined);
console.assert(fun.bind(true)() === true);
Ikkinchidan, qat'iy rejimda ECMAScript kengaytmalari orqali JavaScript stekini “yuritish” endi mumkin emas. Bu kengaytmalarga ega oddiy kodda fun
funksiya chaqirishning o‘rtasida bo‘lsa, fun.caller
oxirgi marta fun
deb atalgan funksiya, fun.arguments
esa fun
'ni chaqirish uchun argumentdir. Ikkala kengaytma ham "xavfsiz" JavaScript uchun muammoli, chunki ular "xavfsiz" kodga "privileged" funktsiyalarga va ularning (potentsial himoyalanmagan) argumentlariga kirishga imkon beradi. Agar fun
qatʼiy rejimda boʻlsa, fun.caller
va fun.arguments
ham oʻchirib boʻlmaydigan xususiyatlar boʻlib, xato qaytaradi:
function restricted() {
'use strict';
restricted.caller; // TypeError qaytaradi
restricted.arguments; // TypeError qaytaradi
}
function privilegedInvoker() {
return restricted();
}
privilegedInvoker();
Brauzerlarda qat'iy rejim.
Taxminan 2012 yildan beri asosiy brauzerlar qat'iy rejimni to'liq joriy qilgan, jumladan IE 10-versiyasi, Firefox 4-versiyasidan beri, Chrome 13-versiyasidan beri va hokazo. Agar siz hali ham qat'iy rejim qo'llab-quvvatlanishidan oldingi juda eski JS environtment ishlatsangiz, JS engine'ga mos keladigan qat'iy bo'lmagan rejimda ishlayotganda uning kutilgan behavior'i buzilmasligini tekshirish uchun qat'iy rejim kodini e'lon qiladigan har qanday kodingizni sinab ko'ring.
Brauzerlarda qat'iy rejim qanday ishlashini hisobga olish kerak bo'lgan ba'zi nuanslar mavjud.
Qat'iy rejim skript yoki funksiyaning yuqori darajasida bo'lmagan function statement
'larni oldini oladi. Brauzerlarda oddiy rejimda function statement
ga hamma joyda ruxsat beriladi. Bu ES5 (yoki hatto ES3) ning bir qismi emas! Bu turli xil brauzerlarda mos kelmaydigan semantikaga ega kengaytma. E'tibor bering, ES2015 da yuqori darajadan tashqarida bo'lgan function statement
'larga ruxsat berilgan.
Masalan, ushbu blok-darajali funksiya deklaratsiyasiga spetsifikatsiya matni tomonidan qat'iy rejimda ruxsat berilmasligi kerak:
if (true) {
function f() { } // !!! syntax error
f();
}
for (var i = 0; i < 5; i++) {
function f2() { } // !!! syntax error
f2();
}
function baz() { // kosher
function eit() { } // also kosher
}
Maqola vanihoyat o'z nihoyasiga yetdi, Sabr bilan ushbu qatorgacha o'riganingiz uchun rahmat. Allah ilmingizni ziyoda qilsin.
Posted on April 25, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.