2015-06-18 2 views
2

У меня сегодня был сюрприз, и я не смог найти соответствующую часть спецификации, чтобы узнать, следует ли это ожидать или нет. Мои деньги на том, что there's nothing wrong with the universe но каковы правила, которые делают это выражение оценивают ложные1 предположительно не равно 1

(function(){ return this;}).call(1) === 1 
+0

добавить «использовать строгое», чтобы исправить это. Строго не принуждает _this_ к объектам. – dandavis

+0

@dandavis спасибо. Я пытаюсь найти часть спецификации, которая делает это так –

ответ

8

каковы правила, которые делают это выражение оценки ложного

В режиме «свободного» в значение this всегда привязывается к объекту. Значения типа объекта не (строго) равны значениям типа Number (или любой другой тип по этому вопросу):

new Number(1) === 1 // false 

От spec:

Ввод кода функции

  1. Если код функции strict code, установите ThisBinding на thisArg.
  2. Else если thisArg является нулевой или неопределенными, установите ThisBinding на глобальный объект.
  3. Иначе, если Type (thisArg) не является объектом, установить ThisBinding к ToObject (thisArg).
    ...
+0

Я не уверен, почему я чувствую, что [Примечание в разделе 'Function.prototype.call'] (http://www.ecma-international.org/ ecma-262/5.1/# sec-15.3.4.4) противоречит ему. – thefourtheye

+0

Не обязательно. Это просто означает, что '.call' сам не выполняет преобразование. –

+0

Хммм, да. Вот как я решил это понять :-) – thefourtheye

0

в зависимости от 'strict mode';

in strict mode: true (type is number) 
without strict mode: false (type is object) 
+0

какая часть спецификации делает это так? –

0

Попробуйте проверить результат этой функции:

(function(){ return this;}).call(1) 

Вы можете видеть, что результат Number {[[PrimitiveValue ]]: 1}, поэтому результат - это не примитивный тип. Так как вы используете три приравнивает вы запрашиваете, что тип и тот же:

(function(){ return this;}).call(1) === 1 // => FALSE 

(function(){ return this;}).call(1) == 1 // => TRUE 

Это не самое странное о Javascript верите мне ;-)

+0

Да, что я знаю, но я искал правило, которое делает это так (это только тот случай, если это не строгий режим) –

2

Примитивный 1 преобразуется в объект Number, когда он установлен в этот в .call потому что этот находится в javascript всегда объект.

И [Номер: 1] не является строго (===) такой же, как примитивного .

Но при использовании не строгого оператора равенства (==) Номер объекта преобразуется в примитив для сравнения.

+0

это может быть примитивным (я узнал, что из-за этого вопроса '(function() {"use strict", return this === 1;}). call (1) 'вернет true –

+0

@Rune FS Хорошо, не знал этого. –

+0

Я тоже :) –

0

(function(){ return this;}).call(1) возвращает объект типа Number, в соответствии с FF developper консоли:

enter image description here

В то время как это 1 примитивного типа.

Смежные вопросы