Случай несогласованности
Может кто-нибудь объяснить следующее?
[] instanceof Array; // true
'' instanceof String; // false
Ответы
Ответ 1
Обратите внимание на следующее:
"" instanceof String; // => false
new String("") instanceof String; // => true
instanceof
требуется объект, но ""
- строковый литерал, а не объект String. Обратите внимание на следующие типы, используя функцию typeof
:
typeof "" // => "string"
typeof new String("") // => "object"
typeof [] // => "object"
typeof new Array() // => "object"
Ответ 2
Это потому, что ''
является примитивным, а не объектом.
Некоторые примитивы в JavaScript могут иметь обертку объекта. Они создаются, когда вы создаете экземпляр оболочки с помощью встроенного конструктора с new
.
new
обычно требуется, потому что часто время, когда функция будет принуждать к примитиву, если вы исключаете new
.
typeof new String(''); // "object"
typeof String(''); // "string"
typeof ''; // "string"
Примитивы с обертками объектов string
, number
и boolean
.
Примитивы, которые не являются null
и undefined
.
Ответ 3
''
не является примером чего-либо; это примитивный тип, и он работает почти так же, как 5.5
или true
. Там разница между примитивом строки и объектом String. См:
new String('') instanceof String; // true
Все, что создано с помощью new String()
, new Number()
или new Boolean()
, является оберткой объекта вокруг примитивного типа, и они не совпадают.
Чтобы проверить строки и т.д., используйте typeof
вместо:
typeof '' === 'string'; // true
Чтобы проверить оба варианта, используйте это:
Object.prototype.toString.call('') === '[object String]'; // true
Object.prototype.toString.call(new String('')) === '[object String]'; // true
Существует несколько причин использовать Object.prototype.toString.call
для общего кода для массивов, строк, чисел и логических элементов. Это:
- Для строк, чисел и логических объектов люди могут передавать экземпляры объектов-оболочек вместо примитивных типов. Они обычно функционируют одинаково (с неявным
valueOf()
), и поэтому вы должны принимать их при написании кода библиотеки.
- Для массивов, если вы получите массив из другого окна (скажем, от
<iframe>
), то с помощью instanceof Array
вернется false
. Метод Object.prototype.toString.call
работает для всех целей.
Это то, что делают jQuery и другие крупные популярные библиотеки.
Ответ 4
Я сделал несколько копаний, и я полагаю, что это связано с string interning, который является оптимизацией компилятора.
Хорошо, готов к некоторым ошибкам?: D
"abc" == "abc"; // true
"abc" === "abc"; // true
Я предполагаю, что это верно из-за "интернационализации строк", который по совпадению также имеет много смысла, концептуально (yay для правильного ввода строк).
new String("abc") == new String("abc"); // false
new String("abc") === new String("abc"); // false
Это имеет смысл, если вы предполагаете, что объект String
является объектом, а объект равен только самому себе и не равен объекту со схожим внутренним состоянием. Как и в Java (или как это было в любом случае).
И теперь для кикера:
(new String("abc")).substr(0,3) === (new String("abc")).substr(0,3); // true!
Таким образом, очевидно, что интерпретатор JavaScript всегда предпочтет интернирование строк над использованием объекта String
.
Затем я должен спросить, что такое использование объекта String
? По-видимому, он не играет со своими друзьями.