Почему оператор 'in' выдает ошибку со строковым литералом вместо логирования false?

Согласно MDN, оператор in возвращает true если свойство существует, и, соответственно, первый пример записывает true. Но когда используется строковый литерал, почему он выдает ошибку, а не регистрирует ложь?

let let1 = new String('test');
console.log(let1.length);
console.log('length' in let1)

Ответ 1

В некотором смысле это вопрос времени. Строковые литералы не имеют никаких свойств. Причина, по которой вы можете вызывать методы и свойства поиска для примитивных строк, заключается в том, что JavaScript автоматически переносит строковый примитив в объект String при попытке вызова метода или поиска свойства. JavaScript не интерпретирует оператор in как вызов метода или поиск свойства, поэтому он не переносит примитив в объект, и вы получаете ошибку (поскольку строковый примитив не является объектом).

См. Разделение между строковыми примитивами и объектами String.

Кроме того, те же документы, на которые есть ссылки в вашем вопросе, специально отмечают, что использование in строковом примитиве вызовет ошибку.

Вы должны указать объект справа от оператора in. Например, вы можете указать строку, созданную с помощью конструктора String, но вы не можете указать строковый литерал.

Ответ 2

Выдает ошибку, потому что в это оператор для объектов:

опора в объект

но когда вы объявляете строку как '' ('строковые (шаблонные) литералы) или "" '' ("," строковые литералы), вы не создаете объект.

Проверьте

typeof new String("x") ("object")

а также

typeof 'x' ("строка").

Это две разные вещи в JavaScript.

Ответ 3

JavaScript оператор in применим только к Object экземпляров.

Когда вы используете конструктор new String('abc') это приведет к созданию экземпляра объекта String.

С другой стороны, когда вы используете только строковые литералы или вызываете функцию String('abc') без new она создает строковый примитив. (вроде Number и Boolen)

Некоторое поведение примитивов и объектов отличается, посмотрите на этот простой пример вывода:

console.log(typeof (new String('ddd'))) // "object"
console.log(typeof ('ddd')) // "string"
console.log(eval('1 + 2')) // 3
console.log(eval(new String('1 + 2'))) // {"0":"1","1":" ","2":"+","3":" ","4":"2"}

Ответ 4

typeof('test') == string (строковый литерал)

typof(new String('test')) == object (строковый объект)

Вы не можете использовать с строковым литералом.

Оператор in возвращает true, если указанное свойство находится в указанном объекте или в его цепочке прототипов.

Ответ 5

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

Первый пример работает и печатает 'true', потому что length является свойством строкового объекта.

Второй пример не работает и выдает ошибку, потому что вы пытаетесь найти length свойства в чем-то (строка), которая не является объектом.