Що робить "use strict" в JavaScript, і які причини цього?

Нещодавно я запустив код мого коду JavaScript через Crockford JSLint , і він дав наступну помилку:

Problem at line 1 character 1: Missing "use strict" statement.

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

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

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

6989
26 авг. заданий Mark Rogers 26 Серпня. 2009-08-26 19:10 '09 о 19:10 2009-08-26 19:10
@ 30 відповідей

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

Процитувати деякі цікаві частини:

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

А також:

Суворий режим допомагає в декількох шляхах:

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

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

 // Non-strict code... (function(){ "use strict"; // Define your library strictly... })(); // Non-strict code... 

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

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

В даний час він підтримується всіма основними браузерами (панель IE 9 і нижче).

4587
26 авг. відповідь дан Pascal MARTIN 26 Серпня. 2009-08-26 19:15 '09 о 19:15 2009-08-26 19:15

Це нова особливість ECMAScript 5. Джон Ресіг написав гарне резюме .

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

border=0
 "use strict"; 

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

+1152
26 авг. відповідь дан seth 26 Серпня. 2009-08-26 19:14 '09 о 19:14 2009-08-26 19:14

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

Список функцій (невичерпний)

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

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

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

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

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

  6. Forbids - восьмеричний синтаксис ( 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]

567
25 нояб. відповідь дан gprasant 25 нояб. 2014-11-25 00:22 '14 в 0:22 2014-11-25 00:22

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

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

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

 function isStrictMode(){ return !this; }  function isStrictMode(){ "use strict"; return !this; }  
385
16 июля '12 в 2:25 2012-07-16 02:25 відповідь дан Jamie Hutber 16 липня '12 о 2:25 2012-07-16 2:25

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

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

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

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

193
03 марта '14 в 10:37 2014-03-03 10:37 відповідь дан DWoldrich 03 березня '14 о 10:37 2014-03-03 10:37

Використання '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 функція Object.createProperty НЕ Object.createProperty відкрита для Object.createProperty функції. Якщо ви спробували привласнити значення для властивості тільки для читання, він буде терпіти невдачі. Призначення не змінить значення властивості, але ваша програма буде діяти так, як якщо б вона була. Це небезпека цілісності, яка може привести до переходу програм в непослідовне стан. У строгому режимі спроба змінити властивість тільки для читання викличе виключення.

восьмеричний

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

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

Et cetera

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

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


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

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

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


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

144
29 янв. відповідь дан sampathsris 29 Січня. 2016-01-29 14:35 '16 о 14:35 2016-01-29 14:35

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

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

наприклад,

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

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

128
05 июля '13 в 22:38 2013-07-05 22:38 відповідь дан Pank 05 липня '13 о 22:38 2013-07-05 22:38

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

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

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

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

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

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

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

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

  • В строгом режиме вы получите TypeError , когда вы пытаетесь назначить свойства readonly или определить новые свойства для не растяжимого объекта. (В обычном режиме оба просто обходятся без сообщения об ошибке.)

  • В строгом режиме при передаче кода в eval() вы не можете объявлять или определять переменные или функции в области вызывающего (как это можно сделать в обычном режиме). Вместо этого для eval() создается новая область, и переменные и функции находятся в пределах этой области. Эта область уничтожается после того, как eval() завершает выполнение.
  • В строгом режиме аргумент-объект функции содержит статическую копию значений, которые передаются этой функции. В нормальном режиме аргумент-объект имеет несколько "магическое" поведение: элементы массива и именованные функциональные параметры ссылаются на одно и то же значение.
  • В строгом режиме вы получите SyntaxError когда за оператором delete следует неквалифицированный идентификатор (переменная, функция или параметр функции). В нормальном режиме выражение delete ничего не сделает и будет оценено как false .
  • В строгом режиме вы получите TypeError при попытке удалить неконфигурируемое свойство. (В обычном режиме попытка просто терпит неудачу, а выражение delete - false ).
  • В строгом режиме это считается синтаксической ошибкой при попытке определить несколько свойств с тем же именем для литерала объекта. (В нормальном режиме ошибки нет.)
  • В строгом режиме это считается синтаксической ошибкой, когда объявление функции имеет несколько параметров с тем же именем. (В нормальном режиме ошибки нет.)
  • В строгом режиме не допускаются восьмеричные литералы (это литералы, начинающиеся с 0x . (В нормальном режиме некоторые реализации позволяют делать восьмеричные литералы).
  • В строгом режиме идентификаторы eval и arguments обрабатываются как ключевые слова. Вы не можете изменить их значение, не можете присвоить им значение, и вы не можете использовать их в качестве имен для переменных, функций, параметров функций или идентификаторов блока catch.
  • В строгом режиме больше ограничений на возможности проверки стека вызовов. arguments.caller и arguments.callee вызывают TypeError в функции в строгом режиме. Кроме того, некоторые свойства caller- и аргументы функций в строгом режиме вызывают TypeError при попытке их прочитать.
88
ответ дан Ely 15 мая '15 в 9:58 2015-05-15 09:58