2016-05-01 8 views
3

Существует чрезвычайно простой алгоритм, который отлично работает в двух случаях, в зависимости от наличия "use strict".Почему строгий режим делает такие простые действия такими разными?

Случай 1:

Если func() декларация находится в строгом режиме, чем консольные журналы примитивного

"use strict"; 

// strict mode is on 
Object.prototype.func = function() { return this; } // do nothing with the object 

console.log((4).func()); // 4; primitive 

Case 2:

Если func() декларации находится вне строгий режим, чем консольные журналы объектов одного и того же значения

// strict mode is off 
Object.prototype.func = function() { return this; } // do nothing with the object 

"use strict"; 

console.log((4).func()); // Number {[[PrimitiveValue]]: 4}; object 

Что является источником такой разницы? В чем причина такого обращения?
Как такие простые действия могут быть разными в разных состояниях строгого режима?

+2

Это в спецификациях * "значение, переданное как' this' функции в строгом режиме, не принудительно превращается в объект (a.k.a. "boxed") "* – adeneo

ответ

3

В этом конкретном примере все, что не является объектом, функцией или массивом, является примитивным. (Функции и массивы являются технически объектами.) Проблема с примитивными значениями заключается в том, что вы не можете иметь методы. Таким образом, вы не могли бы сделать что-то вроде "hello world".toUpperCase(). Вообще говоря, программистам нравится иметь методы, которые относятся к тому типу своего объекта, с которым они работают, чем тонна глобальных доступных функций (например, parseInt).

Так, JavaScript имеет String, Number и другие объекты с методами, как toUpperCase, toLowerCase и toString. Когда мы называем один из этих методов строкой или числом, JavaScript обертывает соответствующий объект, вызывает метод и возвращает примитивный результат. Все это происходит под капотом, и мы, как правило, не должны беспокоиться об этом.

За исключением случаев, когда это не работает, как в вашем примере. Некоторые ошибки были сделаны в ранних версиях JavaScript, но мы не можем реально изменить эти вещи из-за обратной совместимости. Если бы я сделал сайт в 1995 году, который использовал JavaScript, а затем правила изменились в 1997 году, мой сайт внезапно сломается.

Тем не менее, многие из этих ошибок имеют разумные решения, и было бы неплохо, если бы мы могли принять участие в некоторых дополнительных мерах безопасности. Старые браузеры видят, что одинокая строка «использует строгую» и просто игнорирует ее. Новые браузеры увидят это и выберут новый набор правил, обозначенный here.

+0

Отличный ответ, спасибо! Хотя, я не понимаю, почему такие изменения были сделаны вообще (не «распаковывайте» проходящий объект при возврате), - за исключением лучшей оптимизации, возможно ... –

0

this не являющийся в коробке является одним из преднамеренных изменений строгого режима. Это предотвращает доступ JavaScript-кода к примитивам и, таким образом, упрощает его, чтобы доказать, что фрагмент JavaScript является безобидным. Я бы предположил, что он также имеет небольшие улучшения скорости.

Для получения дополнительной информации см. MDN.