"Ciddi rejim" nədir və necə istifadə olunur? Ciddi javascript istifadə edin, bu nədir, java skript xətası Brauzerim Sərt rejimi dəstəkləmirsə nə baş verir




Sərt rejim (“ciddi istifadə” direktivi) JavaScript-də çox yaxşı bir şeydir və işə başlamaq çox asandır!

Bunu necə tətbiq etmək olar // file.js "strict istifadə edin" funksiyası doStuff() ( // sərt rejim aktivləşdirilib)

Yuxarıdakı misalda ciddi rejim file.js-dəki kod boyu tətbiq edilir.

Əgər onu yalnız funksiya daxilində birləşdirmək istəyirsinizsə, aşağıdakı nümunədən istifadə edin:

// file.js funksiyası a () ( "strict istifadə et" ; // ciddi rejim yalnız nestedFunction () funksiyası daxilində kod üçün aktivdir ( // və həmçinin daxili funksiya daxilində istifadə olunacaq ) ) Faydaları Var zombi obyektində düymələri təkrarlayın = ( eyeLeft: 0 , eyeRight: 1 , // ... çoxlu düymələr ... eyeLeft: 1 )

Nəticədə, eyeLeft düyməsi iki dəfə göründüyü üçün xəta alacağıq. Bu halda, ciddi rejim sizi obyektdəki açarın təkrarlanmasından xilas edəcək.

var müstəvisi olmayan dəyişənlər = 5 ;

Dəyişən bəyannaməsinə var açar sözünü əlavə etməyi unutsanız hansı problemlərin yarana biləcəyini yəqin ki, artıq bilirsiniz. Əgər belə deyilsə, onda bilin ki, belə kodu sonradan ayırmaq çox çətindir, çünki belə dəyişən qlobal kontekstdə elan ediləcək və proqramın digər hissələri tərəfindən dəyişdirilə bilər.

Sadəcə qlobal olaraq elan etdiyim dəyişəni təsəvvür edin. Bu, tətbiqdəki bütün iç-içə döngələri darmadağın edə bilər.

Dublikat arqumentlər()

Nəzərə alın ki, fromWhom arqumenti bu halda iki dəfə göstərilib, ciddi rejimdə xəta da göstəriləcək;

Belə bir səhvin nəticələri nələrdir:

funksiyanın icrası (fromWhom, from Whohom ) (alert(fromWhom)) run(1 , 2 ); // xəbərdarlıq: 2 Funksiya daxilində arqumentlərin düzəldilməsi var run = funksiya (fromWhom) ( arqumentlər = "yad" ; alert(fromWhom); ) run("zombi" ); // xəbərdarlıq: "yadplanetli";

Ciddi rejimdən istifadə edirsinizsə:

var run = function (fromWhom) ( "strict istifadə edin" ; arqumentlər = "yad" ; alert(fromWhom); ) run("zombi" ); // xəbərdarlıq: "zombi";

Dəyişən arqumentlərin (arqumentlər = "yad") Kimdən adlı arqumentini dəyişdirməsi nə qədər aydın deyil? "Ciddi istifadə et" direktivi sizi bu çətin vəziyyətdən xilas edəcək.

WoollyMittens, bir reddit istifadəçisi şərhlərdə təklif etdi:

Ciddi rejimlə yanaşı, kodu işə salmazdan əvvəl də axmaq səhvlərdən qaçmaq üçün “linter” (http://www.jshint.com/) quraşdıra bilərsiniz. Əksər redaktorların müvafiq plagini var. Bunları e-poçt yazarkən qrammatik səhvlərinizi vurğulayan eyni qırmızı dalğalı xətlər kimi düşünə bilərsiniz, lakin kodla əlaqədardır.

Tezliklə bütün bunları grunt istifadə edərək necə avtomatlaşdıra biləcəyinizi izah edəcəyəm.

loz220, reddit istifadəçisi

JavaScript - Sərt rejim

Ciddi rejim

Bəzən siz "sloppy mode" adlı qeyri-standart standart rejimi görəcəksiniz. Bu rəsmi termin deyil, ancaq hər ehtimala qarşı onu yadda saxlayın.

(function() ("strict istifadə edin"; false.true = ""; // TypeError (14).sailing = "ev"; // TypeError "with".siz = "uzaqda"; // TypeError ))( );

Dəyişənlərin istifadəsinin sadələşdirilməsi

Sərt rejim dəyişən adlarını kodunuzdakı xüsusi dəyişən təriflərinə uyğunlaşdırmağı asanlaşdırır. Bir çox kompilyator optimallaşdırıcıları bu dəyişəni söyləmək qabiliyyətinə güvənir X-də saxlanılır bu yer: Bu JavaScript kodunuzu tam optimallaşdırmaq üçün vacibdir. JavaScript bəzən icradan əvvəl edilə bilməyən kodda dəyişən tərifə adın bu əsas xəritələşdirilməsini edir. Ciddi rejim bunun baş verdiyi əksər halları aradan qaldırır, beləliklə kompilyator sərt rejim kodunu daha yaxşı optimallaşdıra bilər.

Birincisi, sərt rejim qadağandır. Problem ondadır ki, blok daxilindəki hər hansı ad ya ona ötürülən obyektin xassəsini, ya da işləmə zamanı mühitdəki dəyişəni (və ya hətta qlobal olanı) əks etdirə bilər: bunu əvvəlcədən bilmək üçün heç bir yol yoxdur. Ciddi rejim sintaksis xətası ilə icra olunur, ona görə də a-da işləmə zamanı naməlum yerə istinad edən bir ad üçün heç bir yol yoxdur:

"ciddi istifadə edin"; var x = 17; ilə (obj) ( // !!! sintaksis xətası // Bu "t strict mode" olmasaydı, bu var x olardı, yoxsa // əvəzinə obj.x olardı? Ümumiyyətlə, // mümkün deyil. kodu çalıştırmadan deyin, ona görə də ad // optimallaşdırıla bilməz. x; )

Qısa ad dəyişəninə obyekt təyin etmək, sonra həmin dəyişənin müvafiq xassəsinə daxil olmaq kimi sadə alternativ ilə əvəz etməyə hazırdır.

İkincisi, . Normal kodda eval("var x;") x dəyişənini ətrafdakı funksiyaya və ya qlobal əhatə dairəsinə təqdim edir. Bu o deməkdir ki, ümumi desək, qiymətləndirməyə çağırış ehtiva edən funksiyada hər bir qeyri-arqument və ya yerli dəyişən adı icra zamanı konkret tərifə uyğunlaşdırılmalıdır (çünki bu qiymətləndirmə xarici dəyişəni gizlədən yeni dəyişən təqdim edə bilər). Ciddi rejimdə qiymətləndirmə yalnız qiymətləndirilən kod üçün dəyişənlər yaradır, ona görə də qiymətləndirmə adın xarici dəyişənə və ya bəzi yerli dəyişənə aid olmasına təsir edə bilməz:

Var x = 17; var evalX = eval(""ciddi istifadə edin"; var x = 42; x;"); console.assert(x === 17); console.assert(evalX === 42);

Qiymətləndirmə funksiyası ciddi rejim kodunda eval(...) formasının ifadəsi ilə çağırılırsa, kod ciddi rejim kodu kimi qiymətləndiriləcək. Kod açıq şəkildə sərt rejimə istinad edə bilər, lakin buna ehtiyac yoxdur.

Funksiya strict1(str) ( "strict istifadə edin"; return eval(str); // str ciddi rejim kodu kimi qəbul ediləcək ) funksiya strict2(f, str) ( "strict istifadə edin"; return f(str); // deyil eval(...): str yalnız və yalnız və əgər sərtdir // sərt rejimi çağırırsa ) funksiyası qeyri-strict(str) ( qaytarmaq eval(str); // str yalnız və yalnız o zaman sərtdir // ciddi rejimi çağırırsa ) strict1 (""Ciddi rejim kodu!""); strict1(""strict istifadə et"; "Ciddi rejim kodu!""); strict2(qiymətləndirmə, ""Qeyri-ciddi kod.""); strict2(qiymətləndirmə, ""strict istifadə et"; "Ciddi rejim kodu!""); nonstrict(""Qeyri-ciddi kod."); nonstrict(""strict istifadə edin"; "Ciddi rejim kodu!"");

Beləliklə, ciddi qiymətləndirmə kodundakı adlar, qiymətləndirmənin nəticəsi kimi qiymətləndirilməyən ciddi rejimdəki adlarla eyni davranır.

Üçüncüsü, sərt rejim sadə adların çıxarılmasını qadağan edir. ciddi rejimdə adı silmək sintaksis xətasıdır:

"ciddi istifadə"; var x; sil x; // !!! sintaksis xətası qiymətləndirmə("var y; y sil;"); // !!! söz düzümü səhvi

Qiymətləndirmə və arqumentlərin sadələşdirilməsi

Sərt rejim arqumentləri daha az qəribə və sehrli edir. Hər ikisi normal kodda əhəmiyyətli miqdarda sehrli davranışı ehtiva edir: bağlamaları əlavə etmək və ya silmək və bağlama dəyərlərini dəyişdirmək üçün qiymətləndirmə və arqument adlarında indeksləşdirilmiş ləqəb xüsusiyyətlərindən istifadə edən arqumentlər. Ciddi rejim qiymətləndirmə və arqumentləri açar sözlər kimi qəbul etmək üçün böyük addımlar atır, baxmayaraq ki, ECMAScript-in gələcək buraxılışına qədər tam düzəlişlər görünməyəcək.

Birincisi, qiymətləndirmə və arqument adları dil sintaksisində əlaqələndirilə və ya təyin edilə bilməz. Bütün bu cəhdlər sintaksis xətalarıdır:

"ciddi istifadə edin"; qiymətləndirmə = 17; arqumentlər++; ++qiymətləndirmə; var obj = ( set p(arqumentlər) ( ) ); var qiymətləndirmə; cəhd edin ( ) tutmaq (arqumentlər) ( ) funksiyası x(qiymətləndirmə) ( ) funksiya arqumentləri() ( ) var y = funksiya qiymətləndirmə() ( ); var f = new Function("arqumentlər", ""strict istifadə"; return 17;");

İkincisi, sərt rejim kodu onda yaradılmış arqument obyektlərinin xassələrini dəstəkləmir. Birinci arqumenti arg olan funksiya daxilindəki normal kodda arg parametri də arqumentlər təyin edir və əksinə (heç bir arqument təqdim edilmədikdə və ya arqumentlər silinərsə). arqumentlər ciddi rejim funksiyaları üçün obyektlər funksiya çağırıldıqda orijinal arqumentləri saxlayır. arquments[i] müvafiq adlandırılmış arqumentin dəyərini izləmir, nə də adlandırılmış arqument müvafiq arqumentlərdəki dəyəri izləmir[i] .

Funksiya f(a) ( "ciddi istifadə et"; a = 42; qaytarmaq ; ) var pair = f(17); console.assert(cüt === 42); console.assert(cüt === 17);

Üçüncüsü, arguments.callee artıq dəstəklənmir. Müntəzəm arqumentlərdə.callee bağlama funksiyasına istinad edir. Bu istifadə vəziyyəti zəifdir: sadəcə aktivləşdirmə funksiyasını çağırın! Əlavə olaraq, arguments.callee daxili funksiyalar kimi optimallaşdırmaları daha da çətinləşdirir, çünki access.callee ona daxil olarsa, daxili olmayan funksiyaya istinad təmin etmək lazımdır. ciddi rejim funksiyaları üçün arguments.callee təyin edildikdə və ya götürüldükdə yaradılan istifadə olunmayan xüsusiyyətdir:

"ciddi istifadə"; var f = function() ( arqumentləri qaytarın.callee; ); f(); // TypeError atır

JavaScript-in "mühafizəsi"

Sərt rejim "təhlükəsiz" JavaScript yazmağı asanlaşdırır. Bəzi veb saytlar indi istifadəçilərə veb sayt tərəfindən idarə olunmaq üçün JavaScript yazmaq imkanı verir digər istifadəçilər adından. Brauzerlərdə JavaScript istifadəçinin şəxsi məlumatlarına daxil ola bilər, ona görə də belə JavaScript qadağan edilmiş funksiyalara giriş senzurasına keçməzdən əvvəl qismən çevrilməlidir. JavaScript-in çevikliyi bunu çoxlu iş vaxtı yoxlamaları olmadan etməyi qeyri-mümkün edir. Bəzi dil xüsusiyyətləri o qədər geniş yayılmışdır ki, icra müddəti yoxlamalarının aparılması əhəmiyyətli xərclərə malikdir. Bir neçə ciddi rejim parametrləri, eləcə də istifadəçinin JavaScript-in ciddi rejim kodu olması və onun müəyyən bir şəkildə çağırılması tələbi bu iş vaxtı yoxlamalarına ehtiyacı xeyli azaldır.

Birincisi, ciddi rejimdə funksiyaya funksiya kimi ötürülən dəyər obyektə məcbur edilmir (aka "qutuda"). Normal funksiya üçün bu, həmişə obyektdir: ya obyekt dəyəri ilə çağırılırsa, verilən obyekt; dəyər, qutulu, əgər mantiq, sətir və ya bu nömrə ilə çağırılırsa; və ya qeyri-müəyyən və ya null ilə çağırılan qlobal obyekt. (Xüsusi bunu müəyyən etmək üçün zəng edin, tətbiq edin və ya bağlayın.) Yalnız performans üçün avtoboks deyil, həm də brauzerlərdə qlobal obyektin xəritələşdirilməsi təhlükəsizlik riskidir, çünki qlobal obyekt JavaScript mühitlərini məhdudlaşdırmalı olan "qoruyan" funksiyalara girişi təmin edir. Beləliklə, ciddi rejim funksiyası üçün göstərilən bu obyekt daxilində obyektə yerləşdirilmir və göstərilməsə, bu qeyri-müəyyən olacaq:

"ciddi istifadə edin"; fun() funksiyası ( bunu qaytarın; ) console.assert(fun() === təyin olunmayıb); console.assert(əyləncəli.call(2) === 2); console.assert(fun.apply(null) === null); console.assert(əyləncəli.call(müəyyən edilməmiş) === müəyyən edilməmişdir); console.assert(fun.bind(true)() === true);

Bu o deməkdir ki, başqa şeylərlə yanaşı, sərt rejim funksiyası daxilində bu vasitəsilə pəncərə obyektinə müraciət etmək brauzerlərdə artıq mümkün deyil.

İkincisi, ciddi rejimdə ECMAScript-də ümumi uzantılar vasitəsilə JavaScript şüşəsini “gəzmək” artıq mümkün deyil. Bu uzantıları olan normal kodda fun funksiyası fun.caller funksiyasının ortasında olduqda, fun.caller ən son fun adlandırılan funksiyadır və fun.arguments əyləncəyə çağırış üçün arqumentlərdir. Hər iki genişləndirmə "təhlükəsiz" JavaScript üçün problemlidir, çünki onlar "təhlükəsiz" koda "imtiyazlı" funksiyalara və onların (potensial olaraq təminatsız) arqumentlərinə daxil olmağa imkan verir. Əyləncə ciddi rejimdədirsə, fun.caller və fun.arquments kimi fun.caller fun.arguments xassələri quraşdırıldıqda və ya götürüldükdə atılır:

Function limited() ( "strict istifadə edin"; limited.caller; // TypeError limited.arguments atır; // TypeError atır ) privilegedInvoker() funksiyası ( return limited(); ) privilegedInvoker();

Üçüncüsü, ciddi rejim funksiyaları üçün arqumentlər artıq müvafiq funksiya çağırış dəyişənlərinə girişi təmin etmir. Bəzi köhnə ECMAScript tətbiqlərində arguments.caller xassələri həmin funksiyadakı dəyişənlər tərəfindən dəyişdirilmiş obyekt idi. Bu təhlükəsizlik riskidir, çünki funksiya abstraksiya vasitəsilə imtiyazlı dəyərləri gizlətmək qabiliyyətini pozur; bu da əksər optimallaşdırmaları aradan qaldırır. Bu səbəblərə görə, son brauzerlər bunu həyata keçirmir. Bununla belə, tarixi funksionallığına görə, ciddi rejim funksiyası üçün arguments.caller həm də quraşdırıldıqda və ya götürüldükdə atılan saxta xüsusiyyətdir:

"ciddi istifadə"; fun(a, b) ("strict istifadə et"; var v = 12; arguments.caller qaytarın; // TypeError atır ) fun(1, 2); // v (və ya a və ya b) ifşa etmir

ECMAScript-in gələcək versiyalarına yol açmaq

ECMAScript-in gələcək versiyaları çox güman ki, yeni sintaksis təqdim edəcək və ECMAScript 5-də sərt rejim keçidi asanlaşdırmaq üçün bəzi məhdudiyyətləri tətbiq edir. O dəyişikliklərin əsasını qəti şəkildə qadağan edərsə, bəzi dəyişikliklər etmək daha asan olar.

Birincisi, ciddi rejimdə identifikatorların qısa siyahısı qorunan açar sözlərə çevrilir. Bu sözlər qurğular, interfeys, let, paket, özəl, qorunan, ictimai, statik və gəlirdir. Ciddi rejimdə siz bu adlarla dəyişənləri və ya arqumentləri adlandıra və ya istifadə edə bilməzsiniz.

Funksiya paketi(qorunur) ( // !!! "strict istifadə edin"; var həyata keçirir; // !!! interfeys: // !!! while (doğru) (interfeysi qırmaq; // !!! ) funksiyası özəl( ) ( ) // !!! ) fun(statik) ( "strict istifadə edin"; ) // !!!

Mozilla üçün iki xüsusi xəbərdarlıq: birincisi, kodunuz 1.8 və ya daha böyükdürsə (məsələn, xrom kodunda və ya hüquqdan istifadə edərkən) və ciddi rejim kodudursa, bunlar açar sözlər olduğu üçün ilk dəfə təqdim edildiyi üçün onların let və let funksiyaları var. Lakin İnternetdə ciddi rejim kodu yüklənmiş və ya ..., identifikator kimi let / yield istifadə edə bilməyəcək. İkincisi, ES5 qeyd-şərtsiz olaraq class , enum , export , extensions , import və super sözlərini saxladığı halda, Firefox 5-dən əvvəl Mozilla onları yalnız ciddi rejimdə saxlayır.

İkincisi, . Normal brauzer rejimində funksiya ifadələrinə "hər yerdə" icazə verilir. Bu ES5-in (və ya hətta ES3) bir hissəsi deyil! Bu, brauzerlər arasında uyğun olmayan semantikaya malik uzantıdır. Qeyd edək ki, ES2015 yuxarı səviyyədən kənarda funksiya təsdiqlərinə icazə verir.

"ciddi istifadə"; əgər (doğru) (f() ( ) // !!! sintaksis xətası f(); ) (var i = 0; i) üçün< 5; i++) { function f2() { } // !!! syntax error f2(); } function baz() { // kosher function eit() { } // also kosher }

Bu qadağa ciddi rejim deyil, çünki bu cür funksiya ifadələri ES5 bazasının genişləndirilməsidir. Lakin bu, ECMAScript komitəsinin tövsiyəsidir və brauzerlər bunu həyata keçirir.

Brauzerlərdə sərt rejim

Böyük brauzerlər indi ciddi rejim tətbiq edirlər. Bununla belə, kor-koranə ondan asılı olmayın, çünki təbiətdə hələ də ciddi rejim üçün qismən və ya heç bir dəstəyi olmayan çoxsaylı brauzer versiyaları mövcuddur (məsələn, 10-cu versiyadan aşağı olan Internet Explorer!). Sərt rejim semantikanı dəyişir. Bu dəyişikliklərə güvənmək, ciddi rejimi tətbiq etməyən brauzerlərdə səhvlər və səhvlər təqdim edəcək. Ciddi rejimdən istifadə edərkən ehtiyatlı olun və sərt rejimin müvafiq hissələrinin tətbiq olunduğunu yoxlayan funksional testlərlə ciddi rejimdə inamınızı qoruyun. Nəhayət, mütləq ciddi rejimi dəstəkləyən və dəstəkləməyən brauzerlərdə kodunuzu sınayın. Yalnız ciddi rejimi dəstəkləməyən brauzerlərdə sınaqdan keçirsəniz, çox güman ki, bunu edən brauzerlərdə probleminiz olacaq və əksinə.

Sərt rejim (ingilis dilindən tərcümədə - sərt rejim) JavaScript kodunun təhlili və icrası üçün bir modeldir, səhvlərin yoxlanılması üçün daha ciddi kod istifadə edir və təhlükəli hərəkətlər üçün səhvlər yaradır.

Sərt rejimi aktivləşdirir

Bütün skript üçün ciddi rejimi aktivləşdirmək üçün skriptin əvvəlinə aşağıdakı əmri əlavə edin:

"ciddi istifadə";

O, sətir kimi görünsə də, əslində JavaScript-i sərt rejimə keçirən direktivdir.

Bu direktivi funksiya orqanının əvvəlinə əlavə etməklə fərdi funksiya üçün sərt rejim də aktivləşdirilə bilər:

foo() funksiyası ("ciddi istifadə et"; )

"Ciddi istifadə" direktivi yalnız skriptin ən əvvəlində və ya funksiyanın ən əvvəlində təyin edilə bilər. Bu o demək deyil ki, o, ilk sətirdə olmalıdır, lakin digər ifadələrdən əvvəl sadalanmalıdır. Əgər "sərt istifadə et" direktivi əvvəldən başqa yerdə göstərilibsə, o işləməyəcək:

"ciddi istifadə"; // Düzgün yer a = 5; xəbərdarlıq (a); b = 1; xəbərdarlıq (b); a = 5; xəbərdarlıq (a); "ciddi istifadə"; // Yanlış yer. Direktiv işləməyəcək b = 1; xəbərdarlıq (b);

JavaScript-in sərt rejimdə işlədilməsi
  • Bütün dəyişənlər istifadə edilməzdən əvvəl elan edilməlidir. Elan edilməzdən əvvəl dəyişəni istifadə etməyə çalışmaq istisna yaradır.
  • Elan edilməmiş dəyişənə dəyər təyin etməyə cəhd edərkən xəta baş verir. Bununla belə, qlobal obyektin xassəsini açıq şəkildə yaratmaq və ona dəyər təyin etmək xətaya səbəb olmur: window.num = 10
  • Aşağıdakı sözlər identifikator kimi istifadə edilə bilməz: qiymətləndirmə və arqumentlər .
  • Primitiv dəyərə yeni bir xassə əlavə etməyə çalışmaq istisna yaradır.
  • with ifadəsindən istifadə edə bilməzsiniz.
  • Funksiya parametrləri eyni ada malik ola bilməz.
  • Funksiya parametrləri arqumentlər obyektinin dəyərləri ilə sinxronlaşdırılmır.
  • Əgər funksiya funksiya (metod əvəzinə) kimi çağırılırsa, this açar sözü qlobal obyektə istinaddan çox öz dəyəri kimi qeyri-müəyyənliyi qəbul edir.
  • eval() funksiyasına ötürülən kod qum qutusunda icra olunur, bu o deməkdir ki, kod hələ də mövcud dəyişənləri oxuya və dəyişdirə bilər, lakin ötürülən kodda elan edilmiş dəyişənlər və funksiyalar sandboxdan çıxmayacaq: "use strict"; funksiya foo() ( var a = 10; eval("var x = 10; alert(x + a);"); alert(x); // Xəta. Belə dəyişən mövcud deyil ) foo();
  • Silmə operatorunun operandı yalnız fərdi obyekt xassəsi və ya massiv elementi ola bilər. Silmə operatorunun operandı dəyişənin adı, funksiya, funksiya parametri və ya konfiqurasiya olunmayan xassə adı kimi qeyri-kvalifikatordursa, xəta yaranır.
  • Elan edilməmiş dəyişənlər təyinat zəncirində istifadə edilə bilməz: var a = b = 5; // Xəta. Elan edilməmiş dəyişən (b)
  • Yazıla bilən olmayan bir xüsusiyyətə dəyər təyin etməyə çalışmaq və ya genişlənə bilməyən obyektdə yeni bir xüsusiyyət yaratmaq istisna yaradır.
  • arguments.caller və arguments.callee xassələrinə daxil olmaq istisna yaradır.
  • Blok daxilində FD kimi elan edilən funksiyalar blokun əhatə dairəsindədir: ( foo(); // 1 funksiya foo () ( alert(1); ) ) foo(); // Xəta. foo funksiyası elan edilməyib.

Bəzən siz " " kimi istinad edilən standart, qeyri-ciddi rejimi görərsiniz. Bu rəsmi termin deyil, lakin hər halda bundan xəbərdar olun.

ECMAScript 5-də təqdim edilən JavaScript-in sərt rejimi bir yoldur daxil olun JavaScript-in məhdud variantına, bununla da dolayısı ilə " "-dan imtina edir. Sərt rejim yalnız bir alt çoxluq deyil: o qəsdən normal koddan fərqli semantikaya malikdir. Ciddi rejimi dəstəkləməyən brauzerlər bunu edən brauzerlərdən fərqli davranışlarla ciddi rejim kodu işlədəcəklər, ona görə də ciddi rejimin müvafiq aspektləri üçün dəstək üçün xüsusiyyət sınağı olmadan ciddi rejimə etibar etməyin. Ciddi rejim kodu və qeyri-ciddi rejim kodu ola bilər. birlikdə mövcuddur, buna görə də skriptlər tədricən sərt rejimə keçə bilər.

Sərt rejim normal JavaScript semantikasına bir neçə dəyişiklik edir:

  • Bəzi JavaScript səssiz səhvlərini xəta atmaq üçün dəyişdirərək aradan qaldırır.
  • JavaScript mühərriklərinin optimallaşdırmaları yerinə yetirməsini çətinləşdirən səhvləri düzəldir: ciddi rejim kodu bəzən ciddi rejim olmayan eyni koddan daha sürətli işləmək üçün edilə bilər.
  • ECMAScript-in gələcək versiyalarında müəyyən edilə bilən bəzi sintaksisi qadağan edir.
  • (function() ("strict istifadə edin"; false.true = ""; // TypeError (14).sailing = "ev"; // TypeError "with".siz = "uzaqda"; // TypeError ))( ); Dəyişən istifadələrin sadələşdirilməsi

    Sərt rejim dəyişən adlarının koddakı xüsusi dəyişən tərifləri ilə necə əlaqələndirilməsini asanlaşdırır. Bir çox kompilyator optimallaşdırmaları bu dəyişəni söyləmək qabiliyyətinə əsaslanır X-də saxlanılır ki yer: bu JavaScript kodunu tam optimallaşdırmaq üçün vacibdir. JavaScript bəzən kodun dəyişən tərifinə adın bu əsas xəritələşdirilməsini icra müddətinə qədər yerinə yetirməyi qeyri-mümkün edir. Ciddi rejim bunun baş verdiyi əksər halları aradan qaldırır, beləliklə kompilyator sərt rejim kodunu daha yaxşı optimallaşdıra bilər.

    Birincisi, sərt rejim ilə qadağan edir. Problem ondadır ki, blok daxilində hər hansı bir ad ya ona ötürülən obyektin xüsusiyyətinə, ya da ətrafdakı (və ya hətta qlobal) əhatə dairəsi dəyişəninə işləyə bilər: hansının olduğunu əvvəlcədən bilmək mümkün deyil. rejim sintaksis xətası ilə əmələ gəlir, ona görə də iş zamanı naməlum bir yerə istinad etmək şansı yoxdur:

    "ciddi istifadə edin"; var x = 17; ilə (obj) ( // !!! sintaksis xətası // Bu "t strict mode" olmasaydı, bu var x olardı, yoxsa // əvəzinə obj.x olardı? Ümumiyyətlə, // mümkün deyil. kodu çalıştırmadan deyin, ona görə də ad // optimallaşdırıla bilməz. x; )

    Obyektin qısa ad dəyişəninə təyin edilməsinin sadə alternativi, sonra həmin dəyişənin müvafiq xassəsinə daxil olmaq, ilə əvəz etməyə hazırdır.

    İkincisi, . Normal kodda eval("var x;") ətrafdakı funksiyaya və ya qlobal əhatə dairəsinə x dəyişənini təqdim edir. Bu o deməkdir ki, ümumiyyətlə, qiymətləndirmə çağırışı olan funksiyada arqumentə və ya yerli dəyişənə istinad etməyən hər bir ad icra zamanı xüsusi tərifə uyğunlaşdırılmalıdır (çünki bu qiymətləndirmə xarici dəyişəni gizlədən yeni dəyişən təqdim etmiş ola bilərdi. ). Ciddi rejimdə eval yalnız qiymətləndirilən kod üçün dəyişənlər yaradır, ona görə də qiymətləndirmə adın xarici dəyişənə və ya bəzi yerli dəyişənə aid olmasına təsir göstərə bilməz:

    Var x = 17; var evalX = eval(""ciddi istifadə edin"; var x = 42; x;"); console.assert(x === 17); console.assert(evalX === 42);

    Qiymətləndirmə funksiyası ciddi rejim kodunda eval(...) formasının ifadəsi ilə çağırılırsa, kod ciddi rejim kodu kimi qiymətləndiriləcək. Kod açıq şəkildə sərt rejimi çağıra bilər, lakin bunu etmək lazım deyil.

    Funksiya strict1(str) ( "strict istifadə edin"; return eval(str); // str ciddi rejim kodu kimi qəbul ediləcək ) funksiya strict2(f, str) ( "strict istifadə edin"; return f(str); // deyil eval(...): str yalnız və yalnız və əgər sərtdir // sərt rejimi çağırırsa ) funksiyası qeyri-strict(str) ( qaytarmaq eval(str); // str yalnız və yalnız o zaman sərtdir // ciddi rejimi çağırırsa ) strict1 (""Ciddi rejim kodu!""); strict1(""strict istifadə et"; "Ciddi rejim kodu!""); strict2(qiymətləndirmə, ""Qeyri-ciddi kod.""); strict2(qiymətləndirmə, ""strict istifadə et"; "Ciddi rejim kodu!""); nonstrict(""Qeyri-ciddi kod."); nonstrict(""strict istifadə edin"; "Ciddi rejim kodu!"");

    ciddi rejimdə olan adlar qiymətləndirmə kodu ciddi rejimdə olan adlarla eyni davranır, beləliklə qiymətləndirmənin nəticəsi kimi qiymətləndirilmir.

    Üçüncüsü, sərt rejim sadə adların silinməsini qadağan edir. ciddi rejimdə adı silmək sintaksis xətasıdır:

    "ciddi istifadə"; var x; sil x; // !!! sintaksis xətası qiymətləndirmə("var y; y sil;"); // !!! söz düzümü səhvi

    Qiymətləndirmə və arqumentləri sadələşdirmək

    Sərt rejim arqumentlər və qiymətləndirmələri daha az qəribə sehrli edir. Hər ikisi normal kodda əhəmiyyətli miqdarda sehrli davranışı ehtiva edir: bağlamaları əlavə etmək və ya silmək və bağlama dəyərlərini dəyişdirmək üçün eval və indekslənmiş xassələri ilə arqumentlər adlandırılmış arqumentləri təxmin edir. Ciddi rejim qiymətləndirmə və arqumentləri açar sözlər kimi qəbul etmək istiqamətində böyük addımlar atır, baxmayaraq ki, ECMAScript-in gələcək nəşrinə qədər tam düzəlişlər olmayacaq.

    Birincisi, qiymətləndirmə və arqumentlər dil sintaksisində bağlana və ya təyin edilə bilməz. Bütün bu cəhdlər sintaksis xətalarıdır:

    "ciddi istifadə"; qiymətləndirmə = 17; arqumentlər++; ++qiymətləndirmə; var obj = ( set p(arqumentlər) ( ) ); var qiymətləndirmə; cəhd edin ( ) tutmaq (arqumentlər) ( ) funksiyası x(qiymətləndirmə) ( ) funksiya arqumentləri() ( ) var y = funksiya qiymətləndirmə() ( ); var f = new Function("arqumentlər", ""strict istifadə"; return 17;");

    İkincisi, sərt rejim kodu onun daxilində yaradılmış arqument obyektlərinin xassələrinə ləqəb vermir. Normal kodda birinci arqumenti arg olan funksiya daxilində arg parametri də arqumentlər təyin edir və əksinə (arqumentlər təqdim edilmədikdə və ya arqumentlər silinmədikdə). ciddi rejim funksiyaları üçün arqumentlər obyektləri funksiya çağırıldığı zaman orijinal arqumentləri saxlayır arqumentlər[i] müvafiq adlandırılmış arqumentin dəyərini izləmir, nə də adlandırılmış arqument müvafiq arqumentlərdəki dəyəri izləmir.

    Funksiya f(a) ( "ciddi istifadə et"; a = 42; qaytarmaq ; ) var pair = f(17); console.assert(cüt === 42); console.assert(cüt === 17);

    Üçüncüsü, arguments.callee artıq dəstəklənmir. Normal kodda arguments.callee əhatə edən funksiyaya istinad edir. Bu istifadə halı zəifdir: sadəcə əlavə funksiyanı adlandırın! Bundan əlavə, arguments.callee daxilolma funksiyaları kimi optimallaşdırmalara əhəmiyyətli dərəcədə mane olur, çünki arguments.callee-ə daxil olarsa, daxil edilməmiş funksiyaya istinad təmin etmək mümkün olmalıdır. Ciddi rejim funksiyaları üçün arguments.callee təyin edildikdə və ya əldə edildikdə xəta atan silinməyən bir xüsusiyyətdir:

    "ciddi istifadə"; var f = function() ( arqumentləri qaytarın.callee; ); f(); // TypeError atır

    JavaScript-in "Təhlükəsizliyi"

    Sərt rejim "təhlükəsiz" JavaScript yazmağı asanlaşdırır. Bəzi veb-saytlar indi istifadəçilərə veb sayt tərəfindən idarə olunacaq JavaScript yazmaq üçün yollar təqdim edir digər istifadəçilər adından. Brauzerlərdəki JavaScript istifadəçinin şəxsi məlumatlarına daxil ola bilər, buna görə də JavaScript-in qadağan olunmuş funksionallığına girişi senzura etmək üçün bu cür JavaScript-i qismən dəyişdirmək lazımdır. Müəyyən dil funksiyaları o qədər geniş yayılmışdır ki, iş vaxtı yoxlamalarının aparılması əhəmiyyətli performans xərclərinə səbəb olur. Bir neçə ciddi rejim dəyişikliyi, üstəlik istifadəçi tərəfindən təqdim edilən JavaScript-in ciddi rejim kodu olmasını və onun müəyyən bir şəkildə işə salınmasını tələb edən iş vaxtı yoxlamalarına olan ehtiyacı əhəmiyyətli dərəcədə azaldır.

    Birincisi, ciddi rejimdə funksiyaya bu şəkildə ötürülən dəyər obyekt olmağa məcbur edilmir (a.k.a. "qutulu"). Normal funksiya üçün bu həmişə obyektdir: ya təqdim olunan obyekt obyektlə çağırılırsa this ; dəyər, qutulu, əgər Boolean, sətir və ya bu nömrə ilə çağırılırsa; və ya qeyri-müəyyən və ya null ilə çağırılan qlobal obyekt. (İstifadə edin zəng edin , müraciət edin, və ya bağlamaq konkret bunu müəyyən etmək üçün .) Avtomatik boks nəinki performans dəyəridir, həm də qlobal obyektin brauzerlərdə ifşa edilməsi təhlükəsizlik təhlükəsidir, çünki qlobal obyekt JavaScript mühitlərinin məhdudlaşdırmalı olan "təhlükəsiz" funksiyalarına girişi təmin edir. ciddi rejim funksiyası üçün, göstərilən bu obyektdə qutuya daxil edilmir və müəyyən edilməmişsə, bu qeyri-müəyyən olacaq:

    "ciddi istifadə"; fun() funksiyası ( bunu qaytarın; ) console.assert(fun() === təyin olunmayıb); console.assert(əyləncəli.call(2) === 2); console.assert(fun.apply(null) === null); console.assert(əyləncəli.call(müəyyən edilməmiş) === müəyyən edilməmişdir); console.assert(fun.bind(true)() === true);

    Bu o deməkdir ki, digər şeylərlə yanaşı, brauzerlərdə ciddi rejim funksiyası daxilində pəncərə obyektinə istinad etmək artıq mümkün deyil.

    İkincisi, ciddi rejimdə ECMAScript-ə geniş tətbiq olunan genişləndirmələr vasitəsilə JavaScript yığınını "gəzmək" artıq mümkün deyil. Bu genişlənmələrlə normal kodda, fun funksiya çağırılmanın ortasında olduqda, fun.caller Ən son fun adlandırılan funksiya və fun.arguments əyləncənin çağırılması üçün arqumentlərdir. Əyləncə ciddi rejimdədirsə, həm fun.caller, həm də fun.arqumentlər quraşdırıldıqda və ya geri götürüldükdə atılan silinməyən xüsusiyyətlərdir:

    Function limited() ( "strict istifadə edin"; limited.caller; // TypeError limited.arguments atır; // TypeError atır ) privilegedInvoker() funksiyası ( return limited(); ) privilegedInvoker();

    Üçüncüsü, ciddi rejim funksiyaları üçün arqumentlər artıq müvafiq funksiya çağırışının dəyişənlərinə girişi təmin etmir. Bəzi köhnə ECMAScript tətbiqlərində arguments.caller xassələri həmin funksiyada dəyişənlərə ləqəb verən obyekt idi. Bu təhlükəsizlik təhlükəsidir, çünki o, funksiyanı pozur. funksiyası abstraksiya vasitəsilə imtiyazlı dəyərləri gizlətmək; bu səbəblərə görə heç bir yeni brauzer onu həyata keçirmir, arguments.caller müəyyən edilmiş və ya alındıqda ciddi rejim funksiyası.

    "ciddi istifadə"; fun(a, b) ("strict istifadə et"; var v = 12; arguments.caller qaytarın; // TypeError atır ) fun(1, 2); // v (və ya a və ya b) ifşa etmir

    Gələcək ECMAScript versiyaları üçün yol açmaq

    Gələcək ECMAScript versiyaları çox güman ki, yeni sintaksis təqdim edəcək və ECMAScript 5-də sərt rejim keçidi asanlaşdırmaq üçün bəzi məhdudiyyətlər tətbiq edir. Həmin dəyişikliklərin əsasları ciddi rejimdə qadağan olunarsa, bəzi dəyişikliklər etmək daha asan olacaq.

    Birincisi, ciddi rejimdə identifikatorların qısa siyahısı qorunan açar sözlərə çevrilir. Bu sözlər tətbiqlər, interfeys, icazə, paket, özəl, qorunan, ictimai, statik və gəlirdir. Ciddi rejimdə siz bu adlarla dəyişənləri və ya arqumentləri adlandıra və ya istifadə edə bilməzsiniz.

    Funksiya paketi(qorunur) ( // !!! "strict istifadə edin"; var həyata keçirir; // !!! interfeys: // !!! while (doğru) (interfeysi qırmaq; // !!! ) funksiyası özəl( ) ( ) // !!! ) fun(statik) ( "strict istifadə edin"; ) // !!!

    Mozilla-ya xas iki xəbərdarlıq: Birincisi, kodunuz JavaScript 1.7 və ya daha böyükdürsə (məsələn, xrom kodunda və ya sağdan istifadə edərkən) və sərt rejim kodudursa, icazə verin və bu açar sözlər ilk dəfə təqdim edildikdən sonra əldə etdikləri funksiyalara sahib olsunlar. . Lakin internetdə və ya ... ilə yüklənmiş sərt rejim kodu identifikator kimi let / yield istifadə edə bilməyəcək. İkincisi, ES5 şərtsiz olaraq class , enum , export , extensions , import və super sözlərini saxladığı halda, Firefox 5-dən əvvəl Mozilla onları yalnız ciddi rejimdə saxlamışdı.

    İkincisi, . Brauzerlərdə normal rejimdə funksiya ifadələrinə "hər yerdə" icazə verilir. Bu ES5-in (və ya hətta ES3) bir hissəsi deyil! Bu, müxtəlif brauzerlərdə uyğun olmayan semantikaya malik genişlənmədir. Qeyd edək ki, ES2015-də yuxarı səviyyədən kənar funksiya ifadələrinə icazə verilir.

    "ciddi istifadə"; əgər (doğru) (f() ( ) // !!! sintaksis xətası f(); ) (var i = 0; i) üçün< 5; i++) { function f2() { } // !!! syntax error f2(); } function baz() { // kosher function eit() { } // also kosher }

    Bu qadağa ciddi rejim deyil, çünki bu cür funksiya ifadələri əsas ES5-in genişləndirilməsidir, lakin bu, ECMAScript komitəsinin tövsiyəsidir və brauzerlər bunu həyata keçirəcək.

    Brauzerlərdə sərt rejim

    Əsas brauzerlər indi ciddi rejim tətbiq edirlər. Bununla belə, kor-koranə ondan asılı olmayın, çünki təbiətdə hələ də ciddi rejim üçün qismən dəstək verən və ya ümumiyyətlə dəstəkləməyən çoxsaylı Brauzer versiyaları mövcuddur (məsələn, 10-cu versiyadan aşağı olan Internet Explorer!). Sərt rejim semantikanı dəyişir. Həmin dəyişikliklərə etibar etmək ciddi rejimi tətbiq etməyən brauzerlərdə səhvlərə və xətalara səbəb olacaq. Ciddi rejimdən istifadə edərkən ehtiyatlı olun və ciddi rejimin müvafiq hissələrinin tətbiq edilib-edilmədiyini yoxlayan xüsusiyyət testləri ilə ciddi rejimə etibarınızı ehtiyat nüsxələyin. Nəhayət, mütləq ciddi rejimi dəstəkləyən və dəstəkləməyən brauzerlərdə kodunuzu sınayın. Yalnız ciddi rejimi dəstəkləməyən brauzerlərdə sınaqdan keçirsəniz, çox güman ki, bunu edən brauzerlərdə problem yaranacaq və əksinə.

    Spesifikasiyalar Spesifikasiya Status Şərh
    ECMAScript 5.1 (ECMA-262)
    Standart İlkin tərif. Həmçinin bax:
    ECMAScript 2015 (6-cı Nəşr, ECMA-262)
    Həmin spesifikasiyada "Strict Mode Code" anlayışı.
    Standart Ciddi rejim məhdudiyyəti və istisnalar
    ECMAScript Ən Son Qaralama (ECMA-262)
    Həmin spesifikasiyada "Strict Mode Code" anlayışı.
    Qaralama