Является автозагрузкой javascript?

Во время работы над другой проблемой я создал эту скрипту:

http://jsfiddle.net/tr2by/

function foo() {
    // console.log(_.isBoolean(this));
    console.log(this === true);
}

foo.call(true); // object:[object Boolean]
foo.apply(true); // object:[object Boolean]

Является ли это примером автоматического бокса?

Переход от значения к ссылочному типу.

Вот wikipedia def.

Ответ 1

Прежде всего, я предполагаю, что вы говорите об автоматическом преобразовании примитивных значений в объекты. Это происходит в двух случаях в JavaScript:

  • Когда вы передаете примитивное значение как значение this в .call или .apply (но не в строгом режиме).
  • Когда вы пытаетесь получить доступ к "свойству" примитивного значения, например. "foo bar".split().

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

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


1. Примитивное значение this

Когда функция вызывается и ее значение this не является объектом, оно преобразуется в один, по крайней мере, в нестрогий режим. Это описано в §10.4.3 Ввод кода функции [spec] в документации ECMAScript 5.1:

Следующие шаги выполняются, когда элемент управления вводит контекст выполнения для кода функции, содержащегося в объекте функции F, вызывающего пользователя thisArg и вызывающего пользователя argumentsList:

  • Если код функции является строгим кодом, установите ThisBinding в thisArg.
  • Если значение thisArg равно null или undefined, установите ThisBinding для глобального объекта.
  • Еще если Type(thisArg) не Object, установите ThisBinding в ToObject(thisArg).
    [...]

Как вы можете видеть на шаге три, значение преобразуется в объект, вызывая ToObject [spec].

2. Доступ к свойствам

Что-то подобное происходит, когда вы пытаетесь получить доступ к свойствам (§11.2.1 Аксессоры свойств [spec]), В приведенной здесь части объясняется, как оценивается выражение foo[bar], то есть как оценивается доступ к свойствам с нотной скобкой. Часть, которую мы заинтересованы, также относится к точечной нотации.

Произведение MemberExpression : MemberExpression [ Expression ] оценивается следующим образом:

  • Пусть baseReference является результатом оценки MemberExpression.
  • Пусть baseValue be GetValue(baseReference).
    [...]

  8. Верните значение типа Reference, значение base которого baseValue и имя ссылки которого propertyNameString, а флаг режима strict strict.

Важным шагом является последний: независимо от того, что оценивает MemberExpression, он преобразуется в значение типа Reference [ спецификация]. Это тип данных, используемый только в спецификации, и содержит дополнительную информацию о том, как фактическое значение должно быть извлечено из ссылки (не путать с ссылками на объекты в реальном коде JavaScript!).

Чтобы получить "реальное" значение/результат от такой ссылки, внутренняя функция GetValue(V) (§8.7.1) [spec] (как и на этапе 2 в вышеприведенном алгоритме), где говорится:

Следующий [[Get]] внутренний метод используется GetValue, когда V является ссылкой свойства с базовым значением примитива. Он вызывается с использованием base в качестве значения this и свойства P в качестве аргумента. Сделаны следующие шаги:

  • Пусть O be ToObject(base).
    [...]

Пример:

Предположим, что мы имеем выражение

var foo = "BAR".toLowerCase();

Это выражение присваивания, которое оценивается следующим образом:

Произведение AssignmentExpression : LeftHandSideExpression = AssignmentExpression оценивается следующим образом:

  • Пусть lref будет результатом оценки LeftHandSideExpression.
  • Пусть rref будет результатом оценки AssignmentExpression.
  • Пусть rval be GetValue(rref).
    [...]

Шаг 1: оценивается левая сторона, которая является идентификатором foo. Как именно идентификаторы разрешены, для этого не важно.
Шаг 2: Правая часть оценивается, т.е. "BAR".toLowerCase(). Результат внутреннего этой оценки будет опорным значением, аналогичным:

REFERENCE = {
    base: "BAR",
    propertyNameString: "toLowerCase",
    strict: false
}

и сохранен в rref.

Вызывается этап 3: GetValue(rref). Значением base является значение "BAR". Поскольку это примитивное значение, будет вызван ToObject, чтобы преобразовать его во временный объект String. Кроме того, ссылка на самом деле является доступом к свойствам, поэтому GetValue в конечном итоге вызовет метод toLowerCase в объекте String и вернет результат метода.

Ответ 2

Javascript помещает аргумент this в call и apply в нестрогий режим. Из MDN:

если метод является функцией в коде нестрого режима, null и undefined будут заменены глобальным объектом, а примитивные значения будут помещены в поле.