Strict Mode in Javascript

dawroun

Davron

Posted on April 25, 2022

Strict Mode in Javascript

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:

  1. JavaScript-ning ba'zi bilinmas xatolarini xatolarga o'zgartirish kiritish orqali yo'qotadi.

  2. 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.

  3. 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!";

Enter fullscreen mode Exit fullscreen mode

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"; }

Enter fullscreen mode Exit fullscreen mode

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;

Enter fullscreen mode Exit fullscreen mode

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.

Enter fullscreen mode Exit fullscreen mode

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

Enter fullscreen mode Exit fullscreen mode

Qat'iy rejim o'chirib bo'lmaydigan property'larni o'chirishga urinishlar qiladi :

'use strict';
delete Object.prototype; // TypeError qaytaradi

Enter fullscreen mode Exit fullscreen mode

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!!!
}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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

})();
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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;");
Enter fullscreen mode Exit fullscreen mode

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);
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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);
Enter fullscreen mode Exit fullscreen mode

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();
Enter fullscreen mode Exit fullscreen mode

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 statementga 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
}
Enter fullscreen mode Exit fullscreen mode

Maqola vanihoyat o'z nihoyasiga yetdi, Sabr bilan ushbu qatorgacha o'riganingiz uchun rahmat. Allah ilmingizni ziyoda qilsin.

💖 💪 🙅 🚩
dawroun
Davron

Posted on April 25, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

Strict Mode in Javascript
javascript Strict Mode in Javascript

April 25, 2022