Клавиша / esc
На входе в лес таблички с множеством строгих правил поведения
Иллюстрация: Кира Кустова

use strict

Дополнительные (и строгие!) проверки кода.

Время чтения: 6 мин

Кратко

Скопировано

'use strict' включает строгий режим выполнения JavaScript. Эта строка должна располагаться в самом начале скрипта, иначе строгий режим не будет работать. В строгом режиме интерпретатор будет явно выбрасывать ошибки на действия, которые ранее пропускал. Если строгий режим был включён, то отключить его для файла уже нельзя.

Пример

Скопировано
        
          
          'use strict' // Располагаем строку в самом начале файла!const name = 'Alex'// ... другой код
          'use strict' // Располагаем строку в самом начале файла!

const name = 'Alex'
// ... другой код

        
        
          
        
      

Как понять

Скопировано

Строгий режим был введён в JavaScript со стандартом ECMAScript 5 в 2009 году. Этот стандарт добавил много нового в язык, но чтобы старые браузеры могли продолжать работать, был введён специальный строгий режим выполнения, который включал новые функции языка.

Строгий режим делает следующее:

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

Давайте подробнее посмотрим некоторые важные ограничения, которые накладывает включение строгого режима.

Нельзя использовать переменные без объявления

Скопировано

Интерпретатор в строгом режиме выбросит ошибку, если попытаться присвоить значение переменной без её объявления:

        
          
          'use strict'const name = 'Anna'console.log(name)// Annaage = 24console.log(age)// Uncaught ReferenceError: age is not defined
          'use strict'

const name = 'Anna'
console.log(name)
// Anna

age = 24
console.log(age)
// Uncaught ReferenceError: age is not defined

        
        
          
        
      

Без строгого режима интерпретатор в таком случае создаст переменную age в глобальной области видимости. Если выполнять код из примера в консоли браузера без 'use strict', то все выполнится без ошибок, а в глобальный объект window запишется поле age со значением 24.

☝️ Строгий режим не отменяет «поднятия» (hoisting) var-переменных. Обращение к var-переменной до её объявление не вызовет ошибку:

        
          
          'use strict'console.log(age)// undefinedvar age = 24
          'use strict'

console.log(age)
// undefined

var age = 24

        
        
          
        
      

Явная ошибка если значение поля нельзя изменить или удалить

Скопировано

С помощью методов Object.defineProperty() или Object.preventExtensions() в JavaScript можно запретить перезаписывать поля объекта. При включённом строгом режиме попытка перезаписать поле приведёт к ошибке.

        
          
          'use strict'const obj = {}Object.defineProperty(obj, 'someProp', { value: 'Alex', writable:false })console.log(obj.someProp)// Alexobj.someProp = 'James'// Uncaught TypeError: Cannot assign to read only property 'someProp' of object #<Object>
          'use strict'

const obj = {}

Object.defineProperty(obj, 'someProp', { value: 'Alex', writable:false })

console.log(obj.someProp)
// Alex

obj.someProp = 'James'
// Uncaught TypeError: Cannot assign to read only property 'someProp' of object #<Object>

        
        
          
        
      
        
          
          'use strict'const notExtensableObj = {}Object.preventExtensions(notExtensableObj)notExtensableObj.someProp = 'Value'// Uncaught TypeError: Can't add property someProp, object is not extensible
          'use strict'

const notExtensableObj = {}

Object.preventExtensions(notExtensableObj)

notExtensableObj.someProp = 'Value'
// Uncaught TypeError: Can't add property someProp, object is not extensible

        
        
          
        
      

Ошибка будет выброшена в строгом режиме и при попытке удаления поля из объекта, когда это сделать нельзя.

        
          
          const obj = {}Object.defineProperty(obj, 'someProp', {    value: 'Anna',    configurable: false})delete obj.someProp// Uncaught TypeError: Cannot delete property 'someProp' of #<Object>
          const obj = {}

Object.defineProperty(obj, 'someProp', {
    value: 'Anna',
    configurable: false
})

delete obj.someProp
// Uncaught TypeError: Cannot delete property 'someProp' of #<Object>

        
        
          
        
      

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

Параметры функции не могут иметь одинаковые имена

Скопировано

Если в функции объявить два параметра с одинаковым именем, то строгий режим выбросит ошибку выполнения.

        
          
          'use strict'// Uncaught SyntaxError: Duplicate parameter name not allowed in this contextfunction sum(a, b, a) {  // ...}
          'use strict'

// Uncaught SyntaxError: Duplicate parameter name not allowed in this context
function sum(a, b, a) {
  // ...
}

        
        
          
        
      

Без use strict интерпретатор выполнит код без ошибок.

        
          
          function sum(a, b, a) {  console.log(a)  console.log(b)}sum(1, 2, 3)// 3// 2
          function sum(a, b, a) {
  console.log(a)
  console.log(b)
}

sum(1, 2, 3)
// 3
// 2


        
        
          
        
      

Отмена синхронизации изменения значения параметров и объекта arguments

Скопировано

В строгом режиме объект arguments сохраняет исходные значения аргументов функции. Если в теле функции изменить значение параметра, это не отразится на элементе объекта arguments.

        
          
          'use strict'function f(x) {  x = 0  return [x, arguments[0]]}const result = f(42)console.log(result)// [ 0, 42 ]
          'use strict'

function f(x) {
  x = 0
  return [x, arguments[0]]
}

const result = f(42)

console.log(result)
// [ 0, 42 ]

        
        
          
        
      

Без use strict элемент объекта arguments изменит своё значение:

        
          
          function f(x) {  x = 0  return [x, arguments[0]]}const result = f(42)console.log(result)// [ 0, 0 ]
          function f(x) {
  x = 0
  return [x, arguments[0]]
}

const result = f(42)

console.log(result)
// [ 0, 0 ]

        
        
          
        
      

Другое поведение this

Скопировано

При включённом строгом режиме this больше не будет по умолчанию ссылаться на глобальный объект.

        
          
          'use strict'function logThis() {  console.log(this)}logThis()// Выведет undefined
          'use strict'

function logThis() {
  console.log(this)
}

logThis()
// Выведет undefined

        
        
          
        
      

Без use strict если вызывать функцию в глобальном контексте (например в консоли браузера), то this всегда будет ссылаться на глобальный объект.

Запрещено использовать зарезервированные слова

Скопировано

В строгом режиме запрещено использовать в коде некоторые слова, которые были специально зарезервированы для того, чтобы использовать их в будущем. Это слова implements, interface, let, package, private, protected, public, static, yield. Некоторые из этих слов уже используется в данный момент: например объявление переменных через let или возвращение значения из генератора с помощью yield.

Ограничение небезопасных конструкций

Скопировано

Дополнительно включение строгого режима не позволяет использовать в коде конструкцию with и очищает переменные, созданные с помощью eval(). Обе эти конструкции устарели и являются потенциально опасными, потому не используются в современном JavaScript.

Как пишется

Скопировано

'use strict' называется директивой, так как это не просто строка, а специальная инструкция для интерпретатора. Потому очень важно поместить объявление строгого режима в самом начале скрипта, чтобы это была самая первая строчка, которая исполнится.

        
          
          'use strict' // Включили строгий режим// Далее остальной код
          'use strict' // Включили строгий режим

// Далее остальной код

        
        
          
        
      

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

        
          
          console.log(1 + 2)// 3'use strict' // Просто объявление строки, строгий режим не включился// Код ниже работает без строгого режима
          console.log(1 + 2)
// 3

'use strict' // Просто объявление строки, строгий режим не включился

// Код ниже работает без строгого режима

        
        
          
        
      

Над 'use strict' можно размещать только комментарии.

Строгий режим можно включить для отдельной функции.

        
          
          function useStrictMode() {  "use strict"  function sum(a, b, a) {    console.log(a, b)  }  func(1, 2, 3)}useStrictMode()// Uncaught SyntaxError: Duplicate parameter name not allowed in this context
          function useStrictMode() {
  "use strict"

  function sum(a, b, a) {
    console.log(a, b)
  }

  func(1, 2, 3)
}

useStrictMode()
// Uncaught SyntaxError: Duplicate parameter name not allowed in this context

        
        
          
        
      

Применить строгий режим можно только к функции, которая не использует: