Що означає "строго використовувати" в JavaScript і які міркування за цим?


7547

В останній час , я побіг деякі з мого коду JavaScript через Крокфорд в JSLint , і він дав наступне повідомлення про помилку:

Проблема в рядку 1 символу 1: Відсутнє твердження "використовувати строгий".

Здійснивши пошук, я зрозумів, що деякі люди додають "use strict";у свій код JavaScript. Щойно я додав заяву, помилка перестала з’являтися. На жаль, Google не розкрив багато історії за цим рядковим твердженням. Звичайно, це має бути пов'язане з інтерпретацією браузера браузера JavaScript, але я не маю поняття, який би ефект був би.

Отже, про що йдеться "use strict";, що це означає, і чи це все ще актуально?

Чи відповідає будь-який із поточних веб-переглядачів на "use strict";рядок чи це для подальшого використання?


5
Відповіді тут старі, але вони неправильні. Основне міркування для суворого режиму полягало не у запобіганні помилок програмування - це було зробити JavaScript в лексичному масштабі, щоб він міг статично аналізувати:]
Бенджамін

@BenjaminGruenbaum Використання в "use strict";поодинці не робить JS лексично охопленим. Декларування змінних з letі теж constслід використовувати.
Коорош Пасохі

Ви змішуєте між блоковим обстеженням та лексичним обстеженням.
Бенджамін Груенбаум

Відповіді:


4937

Ця стаття про жорсткий режим Javascript може вас зацікавити: Джон Резиг - жорсткий режим ECMAScript 5, JSON та багато іншого

Процитуйте кілька цікавих частин:

Строгий режим - це нова функція в ECMAScript 5, яка дозволяє розмістити програму або функцію в "суворому" робочому контексті. Цей суворий контекст перешкоджає вчиненню певних дій і спричиняє більше винятків.

І:

Суворий режим допомагає двома способами:

  • Він ловить деякі звичайні кодування bloopers, кидаючи винятки.
  • Він запобігає або видаляє помилки, коли вживаються відносно "небезпечні" дії (наприклад, отримання доступу до глобального об'єкта).
  • Це вимикає функції, які заплутані або погано продумані.

Також зверніть увагу, що ви можете застосувати "суворий режим" до всього файлу ... Або ви можете використовувати його лише для певної функції (все ще цитую статтю Джона Ресіга) :

// Non-strict code...

(function(){
  "use strict";

  // Define your library strictly...
})();

// Non-strict code... 

Що може бути корисним, якщо вам доведеться змішувати старий і новий код ;-)

Отже, я думаю, це трохи схоже на те, що "use strict"ви можете використовувати в Perl (звідси назва?) : Це допомагає вам робити менше помилок, виявляючи більше речей, які можуть призвести до поломки.

Тепер суворий режим підтримується всіма основними браузерами .

Всередині вбудованих модулів ECMAScriptimportта exportоператорами) та класів ES6 суворий режим завжди включений і його неможливо відключити.


100
Зміна дефолту через стільки років? Занадто пізно для цього: це зламає стільки існуючих сайтів / сценаріїв / додатків ... Єдине можливе - допомогти покращити ситуацію на майбутнє.
Паскаль МАРТИН

14
Я спробував невеликий фрагмент коду, який буде недійсним при використанні "use strict"в Firefox 3.6, Safari 5, Chrome 7 та Opera 10.6 (всі Mac). Жодних помилок, тому, мабуть, "використовувати строгий" ще не підтримується в жодному браузері. Не тестував в IE9, хоча;)
Хаскі

11
Швидке оновлення: Firefox 4 має повну підтримку суворого режиму, і наскільки я можу сказати, жоден інший браузер не робить. Safari та Chrome мають "часткову" підтримку, але я не знаю, що це означає.
Саша Чедигов

29
Схоже, Chrome 11 пройшов усі ці тести, як і IE10 ie.microsoft.com/testdrive/HTML5/TryStrict/Default.html#
gman

12
@Julius - Це неможливо було реалізувати за допомогою зарезервованого ключового слова, оскільки тоді код, який намагається запустити суворий режим, у старих веб-переглядачах буде порушений. Додавання "випадкового" рядкового літералу нічого не порушує.
nnnnnn

1245

Це нова особливість ECMAScript 5. Джон Резіг написав хороший підсумок цього.

Це лише рядок, який ви вводите у файли JavaScript (у верхній частині файлу або всередині функції), який виглядає приблизно так:

"use strict";

Якщо ввести його у свій код зараз, це не повинно викликати проблем із поточними браузерами, оскільки це лише рядок. Це може спричинити проблеми з вашим кодом у майбутньому, якщо ваш код порушує прагму. Наприклад, якщо у вас в даний час, foo = "bar"не визначаючи fooспочатку, ваш код почне виходити з ладу ... що, на мій погляд, добре.


328
Невдача швидко і невдало голосно.
Нільс Бом

31
Якщо ви пишете вбудований Javascript у файлах HTML, почніть кожен новий блок із <script>"use strict";. Прапор стосується лише блоку, в який він включений.
nobar

7
Це смішно, в результаті чого рядки повинні мати одинарні лапки. Тож пишіть 'use strict';замість цього
nilsi

1
то що буде з концепцією підключення javascript?
Sunil Sharma

1
@SunilSharma Якщо ви спробуєте підняти, але це не вдається, оскільки змінна не визначена, на даний момент вона додасть її до глобального об'єкта. З "use strict";, замість цього він не вийде. Це має більше сенсу, тому що якщо ви додасте його до глобального об'єкта, це означає, що він може не працювати наступного разу, коли ви запустите функцію / зробите щось інше, що скидає блок, як це буде у найвищому блоці (глобальному).
wizzwizz4

646

Заява "use strict"; вказівку веб-переглядачу використовувати режим суворого режиму, який є скороченим і безпечнішим набором функцій JavaScript.

Перелік функцій (невичерпний)

  1. Вимкнення глобальних змінних. (Ловить відсутні пропуски varі помилки в змінних імен)

  2. Мовчазні невдалі завдання зададуть помилку в суворому режимі (призначаючи NaN = 5;)

  3. Спроби видалити незмінні властивості будуть кинутими (delete Object.prototype )

  4. Потрібно, щоб усі імена властивостей у буквальному об'єкті були унікальними (var x = {x1: "1", x1: "2"} )

  5. Імена параметрів функції повинні бути унікальними (function sum (x, x) {...} )

  6. Забороняє восьмеричний синтаксис (var x = 023; деякі розробники помилково припускають, що попередній нуль не робить нічого для зміни числа.)

  7. Забороняє withключове слово

  8. eval у суворому режимі не вводить нових змінних

  9. Забороняє видаляти прості імена ( delete x;)

  10. Забороняє прив’язувати або присвоювати імена evalта argumentsв будь-якій формі

  11. Строгий режим не псевдоніми властивостей argumentsоб'єкта з формальними параметрами. (тобто в function sum (a,b) { return arguments[0] + b;}цьому працює, тому щоarguments[0] пов'язаний aі так далі.)

  12. arguments.callee не підтримується

[Посилання: Суворий режим , Mozilla Developer Network ]


40
Ніт: глобальні змінні дозволені, просто повинні бути явними (наприклад, window.foo = bar).
gcampbell

1
Потрібно, щоб усі імена властивостей у буквальному об'єкті були унікальними (var x = {x1: "1", x1: "2"}) - це дійсно
Arun Killu

4
У вашому прикладі в 11 відсутня модифікація (інакше це не має сенсу). І. е. сума функцій (a, b) {a = 0; повернути аргументи [0] + b; } попередження (сума (1, 2)) поверне 3 із суворим режимом і 2 без суворого режиму, завдяки згладжуванню.
Девід Гаусман

413

Якщо люди турбуються про use strictйого використання, можливо, варто переглянути цю статтю:

Підтримка ECMAScript 5 "Суворий режим" у браузерах. Що це означає?
NovoGeek.com - веб-журнал Krishna

У ньому йдеться про підтримку браузера, але ще важливіше, як безпечно поводитися з ним:

function isStrictMode(){
    return !this;
} 
/*
   returns false, since 'this' refers to global object and 
   '!this' becomes false
*/

function isStrictMode(){   
    "use strict";
    return !this;
} 
/* 
   returns true, since in strict mode the keyword 'this'
   does not refer to global object, unlike traditional JS. 
   So here, 'this' is 'undefined' and '!this' becomes true.
*/

116
Я не погоджуюсь. Я думаю, це показує, чому це дуже корисно. По суті це означає, що це повертає свою функцію, а неwindow
Джеймі Хатбер

36
коли ти хочеш коли-небудь вікно, на thisяке не можеш націлити window?
Джеймі Хатбер

14
Це стосується себе. thisналежить власній функції, а не глобальному вікну
Джеймі Хатбер

26
У другому this- насправді undefined.
Broxzier

14
Справа в тому, що ваша програма JS почне виходити з ладу через доступ до властивості невизначеного, а не мовчки робити неправильну справу на глобальному об’єкті. Полегшує відстеження тонких помилок набагато простіше.
Стівен Чун

208

Слова обережності, всі ви, програмісти з жорстким зарядом: застосування "use strict"до існуючого коду може бути небезпечним! Ця річ не є якоюсь наклейкою із задоволенням та почуттям щасливого обличчя, яку можна ляпати по коду, щоб зробити її "кращою". З"use strict" прагми браузер раптом БУДЕ виняток у випадкових місцях, які він ніколи раніше не кидав, тільки тому, що на цьому місці ви робите щось, що JavaScript за замовчуванням / непридатність JavaScript щасливо дозволяє, але суворі JavaScript не відповідають! Можливо, у вашому коді рідко використовуються дзвінки, які криються в строго використовуваних дзвінках, які викидають виключення лише тоді, коли в кінцевому підсумку вони запустяться - скажімо, у виробничому середовищі, яким користуються ваші платні клієнти!

Якщо ви збираєтеся поринути, то корисно застосувати "use strict"поряд із комплексними тестами одиниці та строго налаштовану задачу побудови JSHint, яка надасть вам певної впевненості, що не існує темного куточка вашого модуля, який би жахливо вибухнув лише тому, що ви увімкнено суворий режим. Або, ей, ось ще один варіант: просто не додайте "use strict"до свого старого коду, це, мабуть, безпечніше, чесно. ВИЗНАЧЕНО НЕ додайте "use strict"до жодних модулів, якими ви не володієте або не підтримуєте, як-от сторонні модулі.

Я думаю, що навіть це смертельно небезпечна тварина, але це "use strict"може бути хорошою справою, але ви повинні робити це правильно. Найкращий час, коли потрібно суворо ставитися, - це коли ваш проект є «зеленим полем» і ви починаєте з нуля. Налаштуйте JSHint/JSLintвсі попередження та параметри, закручені настільки ж тісно, ​​як ваша команда зможе, отримати хорошу систему складання / тестування / затвердження, яка буде подорожена Grunt+Karma+Chai, і тільки ТОТЕ почніть маркувати всі ваші нові модулі як "use strict". Будьте готові вилікувати безліч помилкових помилок та попереджень. Переконайтесь, що всі розуміють тяжкість, налаштувавши збірку на FAIL, якщо JSHint/JSLintвиникають якісь порушення.

Мій проект не був проектом «зеленого поля», коли я його прийняв "use strict". Як результат, мій IDE переповнений червоними позначками, оскільки я не маю "use strict"на половині своїх модулів, і JSHint скаржиться на це. Це нагадування мені про те, що я повинен робити в майбутньому. Моя мета - позбавити червоних відміток через усі мої пропущені "use strict"заяви, але це вже багато років.


24
ЧОМУ чорти в цій темі настільки кавалер про "використовувати строгий" ?? Це кидає винятки в іншому робочому JavaScript , на користь! Просто посипте його кодом, як цукор на кукурудзяних пластівцях, так? НІ! БАД! "Використовувати суворо" слід використовувати обережно, бажано лише в контрольованому вами коді, який має одиничні тести, які проходять проти всіх основних браузерів і здійснюють усі шляхи коду. Ви отримали тести? Гаразд, "використовувати суворий" - це добре для тебе, вибивай себе.
DWoldrich

57
Так. Очевидно, що "використовувати строгий" може зламати, здавалося б, дійсний JavaScript, який не зламався раніше. Але код, який не зламався раніше, не дорівнює правильності коду і виконанню того, що він повинен. Зазвичай посилання на незадекларовані змінні сигналізує про помилку друку та ін. Використання суворого дозволяє вловлювати подібні помилки, і, сподіваємось, перед тим, як надсилати виробничий код.
Jostein Kjønigsen

5
... або просто застосувати "використовувати строгий" як частину останнього пропуску над вашим кодом, виправити всі очевидні проблеми, знизати плечима, сказати "досить добре", а потім вийняти це для виробництва :)
Wolfie Inu

13
Особисто я ніколи / дуже рідко додаю "use strict"; до існуючого коду. Попри це, я майже завжди буду його використовувати, коли пишу новий код з нуля
Мартін

3
Якщо ви вже використовуєте JSLint, ви, мабуть, виправили більшість місць, де "використовувати суворі строки" все-таки порушить речі.
Джонатан У ролях

179

Використання 'use strict';не раптом покращує ваш код.

Суворий режим JavaScript особливість в ECMAScript 5 . Ви можете ввімкнути суворий режим, оголосивши це у верхній частині сценарію / функції.

'use strict';

Коли двигун JavaScript побачить цю директиву , він почне інтерпретувати код у спеціальному режимі. У цьому режимі помилки викидаються, коли виявляються певні практики кодування, які можуть виявитись потенційними помилками (що є суперечкою суворого режиму).

Розглянемо цей приклад:

var a = 365;
var b = 030;

У своїй одержимості вибудовувати числові літерали розробник ненавмисно ініціалізував змінну bз восьмеричним літералом . Нестрогий режим буде інтерпретувати це як числовий літерал зі значенням 24(у базі 10). Однак суворий режим призведе до помилки.

Для невичерпного переліку спеціальностей у суворому режимі дивіться цю відповідь .


Де я повинен використовувати 'use strict';?

  • У моєму новому додатку JavaScript: абсолютно! Суворий режим може використовуватися як виклик, коли ви робите щось нерозумно зі своїм кодом.

  • У моєму існуючому коді JavaScript: Напевно, ні! Якщо у вашому існуючому коді JavaScript є заяви, заборонені в суворому режимі, програма просто вийде з ладу. Якщо ви хочете суворий режим, вам слід бути готовим до налагодження та виправлення наявного коду. Ось чому використання 'use strict';раптово не покращує ваш код .


Як використовувати суворий режим?

  1. Вставте 'use strict';виписку поверх свого сценарію:

    // File: myscript.js
    
    'use strict';
    var a = 2;
    ....

    Зауважте, що все у файлі myscript.jsбуде інтерпретуватися у суворому режимі.

  2. Або вставте 'use strict';оператор зверху у свій функціональний орган:

    function doSomething() {
        'use strict';
        ...
    }

    Все в лексичному обсязі функції doSomethingбуде інтерпретуватися в суворому режимі. Тут важливим є слово лексична сфера . Наприклад, якщо ваш суворий код викликає функцію бібліотеки, яка не є суворою , тільки ваш код виконується в суворому режимі, а не викликається функцією. Дивіться цю відповідь для кращого пояснення.


Які речі заборонені в суворому режимі?

Я знайшов чудову статтю, що описує кілька речей, заборонених у суворому режимі (зауважте, що це не ексклюзивний список):

Область застосування

Історично JavaScript заплутався у тому, як визначаються функції. Іноді вони, здається, мають статичний обсяг, але деякі функції змушують їх вести себе так, ніби вони динамічно оцінюються. Це заплутано, ускладнює програми для читання та розуміння. Нерозуміння викликає помилки. Це також є проблемою для продуктивності. Статичний діапазон дозволяє дозволити змінній прив'язки відбуватися під час компіляції, але вимога щодо динамічного масштабу означає, що прив'язка повинна бути відкладена на час виконання, що приводить до значного штрафу за продуктивність.

Суворий режим вимагає, щоб всі прив'язки змінної виконувалися статично. Це означає, що функції, які раніше вимагали динамічного зв’язування, повинні бути усунені або модифіковані. Зокрема, оператор with виключено, а здатність функції eval не змінювати навколишнє середовище свого абонента суворо обмежена.

Однією з переваг суворого коду є те, що такі інструменти, як YUI Compressor, можуть зробити кращу роботу при його обробці.

Причетні глобальні змінні

JavaScript має на увазі глобальні змінні. Якщо ви явно не декларуєте змінну, глобальна змінна для вас неявно оголошена. Це полегшує програмування для початківців, оскільки вони можуть нехтувати деякими основними справами по господарству. Але це ускладнює управління більшими програмами і значно погіршує надійність. Тож у суворому режимі маються на увазі глобальні змінні більше не створюються. Вам слід чітко оголосити всі свої змінні.

Глобальний витік

Існує ряд ситуацій, які можуть спричинити this прив'язку до глобального об'єкта. Наприклад, якщо ви забудете надати newпрефікс під час виклику функції конструктора, конструктор thisнесподівано буде прив’язаний до глобального об'єкта, тому замість ініціалізації нового об'єкта він замість того, щоб мовчки підробити глобальні змінні. У таких ситуаціях, строгий режим замість того, щоб зв'язуватися thisз undefined, що викличе конструктор кинути виняток замість цього, дозволяючи помилка буде виявлена набагато раніше.

Шумний збій

JavaScript завжди мав властивості лише для читання, але ви не могли створити їх самостійно, поки Object.createProperty функція ES5 не відкрила цю можливість. Якщо ви спробували призначити значення властивості лише для читання, воно буде мовчати. Призначення не змінить значення властивості, але ваша програма діятиме так, як ніби вона була. Це небезпека цілісності, яка може призвести до переходу програм у невідповідний стан. У суворому режимі спроба змінити властивість лише для читання призведе до виключення.

Октальна

Октальне (або базове 8) подання чисел було надзвичайно корисним при програмуванні на машинному рівні на машинах, розміри яких були кратними 3. Вам потрібен восьмеричний при роботі з мейнфреймом CDC 6600, який має розмір слова 60 біт. Якби ви могли прочитати восьмерику, ви могли поглянути на слово як 20 цифр. Дві цифри представляли оп-код, а одна цифра ототожнювала один з 8 регістрів. Під час повільного переходу від машинних кодів до мов високого рівня вважалося корисним надати вісімкові форми в мовах програмування.

У С було обрано надзвичайно прикро представлення восьмеричності: Провідний нуль. Так що в C 0100означає 64, а не 100, і 08це помилка, а не 8. Ще більше, на жаль, цей анахронізм був скопійований майже у всі сучасні мови, включаючи JavaScript, де він використовується лише для створення помилок. Це не має іншого призначення. Тож у суворому режимі восьмеричні форми більше не допускаються.

Et cetera

Аргумент псевдомасив стає трохи більш схожим на масив в ES5. У строгому режимі, вона втрачає своє calleeі caller властивість. Це дає можливість передавати ваш argumentsненадійний код, не віддаючи багато конфіденційного контексту. Також argumentsусувається властивість функцій.

У суворому режимі дублюючі клавіші у функціональному букварі створюють синтаксичну помилку. Функція не може мати два параметри з однаковою назвою. Функція не може мати змінну з тим самим ім'ям, як один із її параметрів. Функція не може мати deleteвласні змінні. Спроба deleteнеконфігуруваного властивості наражає виняток. Примітивні значення не зафіксовано неявно.


Зарезервовані слова для майбутніх версій JavaScript

ECMAScript 5 додає список зарезервованих слів. Якщо ви використовуєте їх як змінні чи аргументи, суворий режим призведе до помилки. Зарезервовані слова:

implements, interface, let, package, private, protected, public, static, Іyield


Подальше читання


2
це дуже приємне пояснення. Однак у мене є сумніви, що я можу використовувати "суворий" режим спільно з іншими бібліотеками сценаріїв Java, наприклад Angular js?
UVM

3
@UVM: Директива суворого режиму стосується лише лексичної сфери. тобто лише файл / функція, яку він оголосив. Якщо у вас є інший файл / функція, яка не має 'use strict'директиви, вони виконуватимуться в не строгому режимі, навіть коли вони викликаються з функції, що працює в суворому режимі. Дивіться цю відповідь для пояснення.
sampathsris

Це не зовсім правильно. "строго використовувати" змінює спосіб виконання коду.
CyberEd

3
По-друге, ви маєте рацію. Я думав, ти маєш на увазі, що він кидає виключення, але не змінив спосіб роботи коду (як-от зміна this). Тепер я бачу, що ви мали на увазі виклик інших функцій.
CyberEd

3
Існують деякі випадки, коли восьмерик корисний. Синтаксис C для нього жахливий, але мені б хотілося, щоб мови додавали новий восьмеричний синтаксис, який міг би згодом видалити форму "нульовий". Звичайно, що підтримка Javascript підтримувала форму «нульовий лідер» - це просто нерозумно.
supercat

138

Я настійно рекомендую кожному розробнику почати використовувати суворий режим вже зараз. Існує достатня кількість браузерів, які підтримують це, що суворий режим законно допоможе врятувати нас від помилок, про які ми навіть не знали, що у вашому коді.

Мабуть, на початковому етапі будуть помилки, з якими ми жодного разу не стикалися. Щоб отримати повну користь, нам потрібно зробити належне тестування після переходу в суворий режим, щоб переконатися, що ми все зловили. Безумовно, ми не просто вводимо use strictсвій код і припускаємо, що помилок немає. Отже, час полягає в тому, що настав час почати використовувати цю неймовірно корисну функцію мови, щоб написати кращий код.

Наприклад,

var person = {
    name : 'xyz',
    position : 'abc',
    fullname : function () {  "use strict"; return this.name; }
};

JSLint - це налагоджувач, написаний Дугласом Крокфордом. Просто вставте у свій сценарій, і він швидко сканує на наявність помітних проблем та помилок у вашому коді.


6
@JamieHutber: Будь ласка , відвідайте це посилання caniuse.com/use-strict І kangax.github.io/es5-compat-table . Це дасть точну ідею для всіх браузерів.
Панк

95

Я хотів би запропонувати дещо більш обґрунтовану відповідь, доповнюючи інші відповіді. Я сподівався відредагувати найпопулярнішу відповідь, але не вдався. Я намагався зробити це максимально всебічним та повноцінним.

Для отримання додаткової інформації можна звернутися до документації MDN .

"use strict" директива, введена в ECMAScript 5.

Директиви схожі на твердження, але різні.

  • use strictне містить ключових слів: Директива - це просте висловлювання, яке складається з спеціального рядкового літералу (в одинарних або подвійних лапках). Двигуни JavaScript, які не реалізують ECMAScript 5, просто бачать вираз без побічних ефектів. Очікується, що майбутні версії стандартів ECMAScript введуть useяк справжнє ключове слово; Цитати, таким чином, застаріли.
  • use strictможе використовуватися лише на початку сценарію або функції, тобто він повинен передувати кожному іншому (справжньому) оператору. Це не повинно бути першою інструкцією в сценарії функції: їй можуть передувати інші вирази висловлювань, що складаються з рядкових літералів (і реалізація JavaScript може розцінювати їх як директиви, що стосуються реалізації). Висловлювання літеральних рядків, що слідують за першим реальним твердженням (у сценарії чи функції), є простими висловами виразів. Перекладачі не повинні тлумачити їх як директиви, і вони не мають ефекту.

use strictДиректива вказує , що наступний код (в сценарії або функції) строгий код. Код найвищого рівня скрипту (код, який не є функцією) вважається строгим кодом, коли скрипт містить use strictдирективу. Зміст функції вважається суворим кодом, коли сама функція визначена в строгому коді або коли функція містить use strictдирективу. Код, який передається eval()методу, вважається суворим кодом, коли eval()викликається із суворого коду або містить саму use strictдирективу.

Суворий режим ECMAScript 5 - це обмежений підмножина мови JavaScript, що виключає відповідні дефіцити мови та забезпечує більш жорстку перевірку помилок та більш високу безпеку. Далі перелічені відмінності між суворим режимом і звичайним режимом (з яких перші три особливо важливі):

  • Не можна використовувати withтвердження в суворому режимі.
  • У суворому режимі всі змінні повинні бути задекларовані: якщо ви присвоїте значення ідентифікатору, який не був оголошений змінною, функцією, функціональним параметром, параметром «catch-clause» або властивістю глобального Object, ви отримаєте a ReferenceError. У звичайному режимі ідентифікатор неявно оголошується глобальною змінною (як властивість глобальної Object)
  • У суворому режимі ключове слово thisмає значення undefinedу функціях, які викликали як функції (а не як методи). (У звичайному режимі thisзавжди вказує на глобальний Object). Цю різницю можна використовувати для тестування, чи реалізація підтримує суворий режим:
var hasStrictMode = (function() { "use strict"; return this===undefined }());
  • Крім того, коли функція викликається call()або applyв суворому режимі, то thisсаме це значення першого аргументу call()або apply()виклику. (В нормальному режимі nullі undefinedзамінюються глобальної Objectі значеннями, які не є об'єктами, відлиті в об'єкти.)

  • У суворому режимі ви отримаєте TypeError, коли ви спробуєте призначити властивості лише для читання або визначити нові властивості для нерозширюваного об'єкта. (У звичайному режимі обидва просто відмовляються без повідомлення про помилку.)

  • У суворому режимі під час передачі коду eval()не можна оголошувати або визначати змінні чи функції в межах виклику (як це можна зробити у звичайному режимі). Натомість створюється нова область застосування, eval()і змінні та функції знаходяться в межах цієї сфери. Цей обсяг руйнується після eval()закінчення виконання.
  • У жорсткому режимі аргумент-об’єкт функції містить статичну копію значень, які передаються цій функції. У звичайному режимі аргумент-об’єкт має дещо "магічну" поведінку: елементи масиву та названі параметри функції посилаються на те саме значення.
  • У суворому режимі ви отримаєте, SyntaxErrorколи deleteоператор супроводжується некваліфікованим ідентифікатором (змінною, функцією або параметром функції). У звичайному режимі deleteвираз нічого не зробить і його оцінюють false.
  • У суворому режимі ви отримаєте, TypeErrorколи ви спробуєте видалити неконфігуруване властивість. (У звичайному режимі спроба просто провалюється, і deleteвираз оцінюється на false).
  • У суворому режимі це вважається синтаксичною помилкою, коли ви намагаєтеся визначити кілька властивостей з однаковою назвою для буквеного об'єкта. (У звичайному режимі помилок немає.)
  • У суворому режимі вважається синтаксичною помилкою, коли в декларації функції є кілька параметрів з однаковою назвою. (У звичайному режимі помилок немає.)
  • У суворому режимі восьмі літерали заборонені (це літерали, які починаються з 0x. (У звичайному режимі деякі реалізації дозволяють використовувати восьмеричні літерали.)
  • У строгому режимі ідентифікатори evalі argumentsрозглядаються як ключові слова. Ви не можете змінити їх значення, не можете призначити їм значення, і ви не можете використовувати їх як імена змінних, функцій, параметрів функції або ідентифікаторів блоку вилову.
  • У суворому режимі більше обмежень щодо можливості перевірки стеку викликів. arguments.callerі arguments.calleeвикликати функцію TypeErrora у суворому режимі. Крім того, деякі властивості функцій викликів та аргументів у суворому режимі викликають а, TypeErrorколи ви намагаєтесь їх прочитати.

4
"У суворому режимі восьмі літерали не дозволені (це літерали, які починаються з 0x ...)" восьмеричні літерали починаються з ведучого 0.
Алекс Гіттемайер

83

Мої два центи:

Однією з цілей суворого режиму є забезпечення швидшої налагодження питань. Це допомагає розробникам, кидаючи винятки, коли трапляються певні неправильні речі, які можуть спричинити мовчазне та дивне поведінку вашої веб-сторінки. Щойно ми використовуємо use strict, код викине помилки, що допоможе розробнику виправити його заздалегідь.

Кілька важливих речей, які я дізнався після використання use strict:

Запобігає декларації глобальної змінної:

var tree1Data = { name: 'Banana Tree',age: 100,leafCount: 100000};

function Tree(typeOfTree) {
    var age;
    var leafCount;

    age = typeOfTree.age;
    leafCount = typeOfTree.leafCount;
    nameoftree = typeOfTree.name;
};

var tree1 = new Tree(tree1Data);
console.log(window);

Тепер цей код створюється nameoftreeв глобальному масштабі, до якого можна отримати доступ за допомогою window.nameoftree. Коли ми реалізовуємо use strictкод, це призведе до помилки.

Uncaught ReferenceError: nameoftree не визначено

Sample

Усуває withзаяву:

withоператори не можуть бути мінімізовані за допомогою таких інструментів, як uglify-js . Вони також застаріли та видалені з майбутніх версій JavaScript.

Sample

Запобігає дублювання:

Коли ми маємо повторюване властивість, це кидає виняток

Uncaught SyntaxError: У суворому режимі копіювання властивостей даних у літералі об'єкта заборонено

"use strict";
var tree1Data = {
    name: 'Banana Tree',
    age: 100,
    leafCount: 100000,
    name:'Banana Tree'
};

Є ще кілька, але мені потрібно отримати більше знань з цього приводу.


З ECMAScript 2015 повторювані імена властивостей дозволені знову! Див. Документацію MDN .
philmcole

62

Якщо ви користуєтеся браузером, випущеним за останній рік або близько того, він, швидше за все, підтримує жорсткий режим JavaScript. Лише старі веб-переглядачі, перш ніж ECMAScript 5 став чинним стандартом, не підтримують його.

Цитати навколо команди переконайтеся, що код все ще працюватиме і в старих браузерах (хоча речі, які генерують синтаксичну помилку в суворому режимі, як правило, просто спричиняють несправність сценарію в деяких важко виявлених способах у тих старих браузерах).


12
Тоді що це робить?
Аніш Гупта

7
... це частково описує сумісність, але не те, що вона насправді робить.
Courtimas

58

При додаванні "use strict"; наступні випадки передають SyntaxError перед виконанням сценарію:

  • Прокладаючи шлях для версій майбутнього ECMAScript , використовуючи один з недавно зарезервованих ключових слів (в передбаченні для ECMAScript 6 ): implements, interface, let, package, private,protected , public, static, і yield.

  • Декларування функції в блоках

    if(a<b){ function f(){} }
  • Октальний синтаксис

    var n = 023;
  • this вказують на глобальний об’єкт.

     function f() {
          "use strict";
          this.a = 1;
     };
     f(); 
  • Оголошення в два рази однакового імені для імені властивості в буквальному об'єкті

     {a: 1, b: 3, a: 7} 

    У ECMAScript 6 це більше не відбувається ( помилка 1041128 ).

  • Оголошення двох аргументів функції з одноіменною функцією

    f(a, b, b){}
  • Встановлення значення незадекларованої змінної

    function f(x){
       "use strict";
       var a = 12;
       b = a + x*35; // error!
    }
    f();
  • Використання deleteназви змінноїdelete myVariable;

  • Використання evalабо argumentsяк ім'я аргументу змінної або функції

    "use strict";
    arguments++;
    var obj = { set p(arguments) { } };
    try { } catch (arguments) { }
    function arguments() { } 

Джерела:


З ECMAScript 2015 повторювані імена властивостей дозволені знову! Див. Документацію MDN .
philmcole

53

Суворий режим вносить кілька змін у звичайну семантику JavaScript:

  • усуває деякі мовчазні помилки JavaScript, змінюючи їх для видалення помилок.

  • виправляє помилки, які ускладнюють роботи двигунів JavaScript в оптимізації.

  • забороняє деякий синтаксис, який, можливо, буде визначений у майбутніх версіях ECMAScript.

для отримання додаткової інформації суворого режиму - javascript


52

"Використовуйте суворо"; - це страхування того, що програміст не буде використовувати слабкі або погані властивості JavaScript. Це посібник, як і лінійка допоможе вам зробити прямі лінії. "Use Strict" допоможе вам зробити "прямого кодування".

Ті, хто вважає за краще не використовувати лінійки для прямолінійного виконання рядків, зазвичай потрапляють на ці сторінки з проханням інших відладжувати код.

Повір мені. Накладні витрати незначні порівняно з неякісно розробленим кодом. Дуг Крокфорд, який вже кілька років є старшим розробником JavaScript, має тут дуже цікавий пост . Особисто мені подобається постійно повертатися на його сайт, щоб переконатися, що я не забуваю про свою хорошу практику.

Сучасна практика JavaScript завжди повинна викликати "Строго використання"; прагма. Єдина причина, за якою Група ECMA зробила режим "Суворий" необов'язковим, - це дозволяти менш досвідченим кодерам доступ до JavaScript і надавати час для адаптації до нових і безпечніших методів кодування.


66
Причина того, що суворий режим не є обов'язковим, не має нічого спільного з тим, що ви заявили. Справжня причина - не порушити існуючий код, який може не відповідати .
Dexygen

17
Дійсно, менш досвідчені кодери повинні бути першими , щоб дозволити "використовувати суворо";
Антті Хаапала

46

Включення use strictна початку всіх чутливих файлів JavaScript з цього моменту - це малий спосіб бути кращим програмістом JavaScript і уникати випадкових змінних, що стають глобальними, і все змінюється мовчки.


42

Цитування з w3schools :

Директива "суворо використовувати"

Директива "використовувати суворий" нова в JavaScript 1.8.5 (версія ECMAScript 5).

Це не твердження, а буквальний вираз, ігнорований попередніми версіями JavaScript.

Мета "строгого використання" - вказати, що код повинен виконуватися в "суворому режимі".

При суворому режимі не можна, наприклад, використовувати незадекларовані змінні.

Чому суворий режим?

Суворий режим спрощує написання "захищеного" JavaScript.

Суворий режим змінює раніше прийнятий «поганий синтаксис» на справжні помилки.

Наприклад, у звичайному JavaScript помилкове введення ім'я змінної створює нову глобальну змінну. У жорсткому режимі це призведе до помилки, унеможливлюючи випадкове створення глобальної змінної.

У звичайному JavaScript розробник не отримуватиме зворотного зв’язку з помилками, присвоюючи значення властивостям, що не записуються.

У суворому режимі будь-яке присвоєння властивості, що не записується, властивості лише для отримання, неіснуючої властивості, неіснуючої змінної або неіснуючого об'єкта призведе до помилки.

Щоб дізнатися більше, зверніться до http://www.w3schools.com/js/js_strict.asp


37

"use strict"змушує код JavaScript працювати в суворому режимі , що в основному означає, що все потрібно визначити перед використанням. Основна причина використання суворого режиму - уникати випадкових глобальних застосувань невизначених методів.

Також у суворому режимі все працює швидше, деякі попередження або тихі попередження призводять до фатальних помилок, краще завжди використовувати його для створення акуратного коду.

"use strict"широко використовується для використання в ECMA5, в ECMA6 це частина JavaScript за замовчуванням , тому його не потрібно додавати, якщо ви використовуєте ES6.

Подивіться на ці твердження та приклади з MDN:

Директива
"суворо використовувати" Директива "суворо використовувати" є новою в JavaScript 1.8.5 (версія ECMAScript 5). Це не твердження, а буквальний вираз, ігнорований попередніми версіями JavaScript. Мета "строгого використання" - вказати, що код повинен виконуватися в "суворому режимі". При суворому режимі не можна, наприклад, використовувати незадекларовані змінні.

Приклади використання "строгого використання":
Суворий режим для функцій: Так само, щоб викликати суворий режим для функції, поставте точне твердження "використовувати строгий"; (або "використовувати строго";) в тілі функції перед будь-якими іншими твердженнями.

1) суворий режим у функціях

 function strict() {
     // Function-level strict mode syntax
     'use strict';
     function nested() { return 'And so am I!'; }
     return "Hi!  I'm a strict mode function!  " + nested();
 }
 function notStrict() { return "I'm not strict."; }

 console.log(strict(), notStrict());

2) суворий сценарій суворого режиму

'use strict';
var v = "Hi! I'm a strict mode script!";
console.log(v);

3) Присвоєння глобальному, що не записується

'use strict';

// Assignment to a non-writable global
var undefined = 5; // throws a TypeError
var Infinity = 5; // throws a TypeError

// Assignment to a non-writable property
var obj1 = {};
Object.defineProperty(obj1, 'x', { value: 42, writable: false });
obj1.x = 9; // throws a TypeError

// Assignment to a getter-only property
var obj2 = { get x() { return 17; } };
obj2.x = 5; // throws a TypeError

// Assignment to a new property on a non-extensible object.
var fixed = {};
Object.preventExtensions(fixed);
fixed.newProp = 'ohai'; // throws a TypeError

Детальніше ви можете прочитати на MDN .


31

Деякі люди, які були в комітеті ECMAScript, добре поговорили: Зміни JavaScript, частина 1: ECMAScript 5 " про те, як поступово використовувати"use strict" комутатора дозволяє реалізаторам JavaScript очистити безліч небезпечних особливостей JavaScript, не раптово порушуючи кожен веб-сайт в світі.

Звичайно, це також говорить про те, що багато таких випадків є (як), і як ECMAScript 5 виправляє їх.


27

Невеликі приклади для порівняння:

Не суворий режим:

for (i of [1,2,3]) console.log(i)
    
// output:
// 1
// 2
// 3

Суворий режим:

'use strict';
for (i of [1,2,3]) console.log(i)

// output:
// Uncaught ReferenceError: i is not defined

Не суворий режим:

String.prototype.test = function () {
  console.log(typeof this === 'string');
};

'a'.test();

// output
// false

String.prototype.test = function () {
  'use strict';
  
  console.log(typeof this === 'string');
};

'a'.test();

// output
// true


2
Зауважте, що наведений вище код додасть змінну i в глобальну область застосування (зазвичай це не найкраща практика, а суворий режим допомагає цього уникнути).
Майкл

1
Чи може хтось пояснити другий приклад? Я не розумію. Чи не повинні this === 'a'в обох прикладах?
MaximeW

19

Зауважте, що він use strictбув введений в EcmaScript 5 і зберігався з тих пір.

Нижче наведено умови для запуску строгого режиму в ES6 та ES7 :

  • Глобальний код - це режим суворого режиму, якщо він починається з Прологу Директиви, який містить Директиву суворої експлуатації (див. 14.1.1).
  • Код модуля - це завжди строгий код режиму.
  • Усі частини ClassDeclaration або ClassExpression є суворим режимом коду.
  • Код Eval - це код суворого режиму, якщо він починається з Прологу Директиви, який містить Директиву суворої експлуатації, або якщо заклик до eval є прямим eval (див. 12.3.4.1), який міститься у строгому режимі коду.
  • Код функції - це суворий режим режиму, якщо пов'язаний FunctionDeclaration, FunctionExpression, GeneratorDeclaration, GeneratorExpression, MethodDefinition або ArrowFunction міститься в коді суворого режиму або якщо код, який виробляє значення внутрішнього слота функції [[ECMAScriptCode]], починається з директивного прологу що містить сувору директиву щодо використання.
  • Код функції, який подається в якості аргументів вбудованим конструкторам функцій та генераторів, є строгим кодом режиму, якщо останнім аргументом є String, який при обробці - це FunctionBody, що починається з прологу Директиви, що містить Директиву використання строгих строків.

14

Основні причини, чому розробники повинні використовувати "use strict":

  1. Запобігає випадковому оголошенню глобальних змінних . Використання "use strict()"гарантує, що змінні декларуються varперед використанням. Наприклад:

    function useStrictDemo(){
     'use strict';
     //works fine
     var a = 'No Problem';
    
     //does not work fine and throws error
     k = "problem"
    
     //even this will throw error
     someObject = {'problem': 'lot of problem'};
    }
  2. Примітка: "use strict"Директива розпізнається лише на початку сценарію або функції.
  3. Рядок "arguments"не можна використовувати як змінну:

    "use strict";
    var arguments = 3.14;    // This will cause an error
  4. Обмежить використання ключових слів як змінних. При спробі їх використання викличуть помилки.

Коротше кажучи, зробить ваш код менш схильним до помилок, а в свою чергу змусить вас написати хороший код.

Щоб прочитати більше про це, ви можете звернутися тут .


12

"використовувати суворо"; це зусилля ECMA, щоб зробити JavaScript трохи більш надійним. Це приносить JS спробу зробити його хоч трохи «суворим» (інші мови застосовують суворі правила з 90-х). Це насправді "змушує" розробників JavaScript дотримуватися певного методу кодування. Тим не менш, JavaScript дуже крихкий. Немає такого поняття, як введені змінні, введені методи тощо. Настійно рекомендую розробникам JavaScript вивчити більш надійну мову, наприклад, Java або ActionScript3, та впровадити ті самі найкращі практики у свій код JavaScript, це буде працювати краще і легше налагоджувати.


12

У "ECMAScript 5" було введено "суворий" режим JavaScript.

(function() {
  "use strict";
  your code...
})();

Запис "use strict";у верхній частині вашого файлу JS вмикає сувору перевірку синтаксису. Він виконує наступні завдання для нас:

  1. показує помилку, якщо ви намагаєтесь призначити незадекларовану змінну

  2. не дозволяє перезаписати ключові системні бібліотеки JS

  3. забороняє деякі небезпечні або схильні до помилок функції мови

use strictтакож працює всередині окремих функцій. Це завжди краща практика включити use strictу свій код.

Проблема сумісності веб-переглядачів: Директиви "використання" мають бути сумісними назад. Веб-переглядачі, які не підтримують їх, просто побачать літеральний рядок, на який далі не посилаються. Отже, вони перейдуть це і рухатимуться далі.


12

use strictце спосіб зробити свій код більш безпечним, оскільки ви не можете використовувати небезпечні функції, які можуть працювати не так, як ви очікували. І, як писалося раніше, він робить код більш суворим.


11

Use Strict використовується для відображення поширених та повторних помилок, щоб оброблятись по-різному та змінювати спосіб виконання сценарію java, такі зміни:

  • Запобігає випадковим глобалам

  • Дублікатів немає

  • Усуває с

  • Усуває цей примус

  • Безпечніший eval ()

  • Помилки непорушних

Ви також можете прочитати цю статтю для деталей


11

Зазвичай JavaScript не дотримується суворих правил, отже збільшуються шанси помилок. Після використання "use strict"коду JavaScript слід дотримуватися суворого набору правил, як в інших мовах програмування, таких як використання термінаторів, декларація перед ініціалізацією тощо.

Якщо "use strict"використовується, код слід писати, дотримуючись суворого набору правил, отже, зменшуючи шанси помилок та неясностей.


7

"використовувати суворо"; Визначає, що JavaScript-код повинен виконуватися в "суворому режимі".

  • Директива "суворо використовувати" була нова у версії 5 ECMAScript.
  • Це не твердження, а буквальний вираз, ігнорований попередніми версіями JavaScript.
  • Мета "строгого використання" - вказати, що код повинен виконуватися в "суворому режимі".
  • При суворому режимі не можна, наприклад, використовувати незадекларовані змінні.

Усі сучасні веб-переглядачі підтримують "суворий режим", за винятком Internet Explorer 9 і новіших версій .

Недоліки

Якщо розробник використовував бібліотеку, яка перебуває в суворому режимі, але розробник звик працювати в звичайному режимі, вони можуть викликати деякі дії над бібліотекою, які не працюватимуть, як очікувалося.

Гірше, оскільки розробник перебуває у звичайному режимі, у них немає переваг видалення зайвих помилок, тому помилка може вийти з ладу.

Також, як зазначено вище, суворий режим не дозволяє вам робити певні речі.

Люди, як правило, вважають, що ви не повинні користуватися цими речами в першу чергу, але деякі розробники не люблять обмеження і хочуть використовувати всі функції мови.


4

Суворий режим може запобігти витоку пам'яті.

Будь ласка, перевірте функцію, написану нижче, у строгому режимі:

function getname(){
    name = "Stack Overflow"; // Not using var keyword
    return name;
}
getname();
console.log(name); // Stack Overflow

У цій функції ми використовуємо змінну, яку називають nameусередині функції. Внутрішньо компілятор спочатку перевірить, чи є якась змінна, оголошена з цим конкретним іменем у цій конкретній області функцій. Оскільки компілятор зрозумів, що такої змінної немає, вона перевіриться у зовнішній області. У нашому випадку це глобальна сфера. Знову ж таки, компілятор зрозумів, що в глобальному просторі з цим ім'ям також не існує змінної, тому він створює таку змінну для нас у глобальному просторі. Концептуально ця змінна буде створена в глобальному масштабі та буде доступна у всій програмі.

Інший сценарій полягає в тому, що, скажімо, змінна оголошується у дочірній функції. У цьому випадку компілятор перевіряє дійсність цієї змінної у зовнішній області, тобто батьківській функції. Тільки тоді він перевірить у глобальному просторі і створить там змінну для нас. Це означає, що потрібно зробити додаткові перевірки. Це вплине на продуктивність програми.


Тепер запишемо ту саму функцію в суворому режимі.

"use strict"
function getname(){
    name = "Stack Overflow"; // Not using var keyword
    return name;
}
getname();
console.log(name); 

Ми отримаємо таку помилку.

Uncaught ReferenceError: name is not defined
at getname (<anonymous>:3:15)
at <anonymous>:6:5

Тут компілятор викидає посилальну помилку. У суворому режимі компілятор не дозволяє нам використовувати змінну, не оголошуючи її. Так витоки пам'яті можна запобігти. Крім того, ми можемо написати більш оптимізований код.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.