Для строк JS всегда ли s === "" то же самое, что s.length == 0? - PullRequest
2 голосов
/ 25 мая 2020

Для строк JS s === "" всегда совпадает с s.length == 0?

Ответы [ 2 ]

9 голосов
/ 25 мая 2020

Исключение составляет крайний случай, когда s - это строка объект вместо строки примитив :

const s = new String("");
console.log(s.length === 0); // true
console.log(s === "");       // false

s === "" не работает, потому что === не выполняет преобразование типов, поэтому объект никогда не === в примитив.

JavaScript немного необычен тем, что имеет объектные эквиваленты своих примитивных типов. Вы почти всегда имеете дело со строковыми примитивами, а не со строковыми объектами, но строковые объекты действительно существуют, и это различие может быть допустимым. Сейчас это гораздо менее важно знать, чем раньше. Еще до строгого режима ES5, если вы расширили String.prototype методом isEmpty (например), ваша проверка length === 0 будет работать, а === "" - нет:

// Very old loose-mode pre-ES5 code
String.prototype.wrongIsEmpty = function() {
    return this === ""; // WRONG
};
String.prototype.rightIsEmpty = function() {
    return this.length === 0; // Right
};

console.log("".wrongIsEmpty()); // false
console.log("".rightIsEmpty()); // true

Причина проблемы в том, что до строгого режима ES5 this в функции всегда был объектом, а не примитивом, поэтому эти методы видят строку object as this.

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

"use strict";

Object.defineProperty(String.prototype, "isEmpty1", {
    value: function() {
        return this === ""; // This is fine
    },
    writable: true,
    configurable: true
});
Object.defineProperty(String.prototype, "isEmpty2", {
    value: function() {
        return this.length === 0; // This is fine
    },
    writable: true,
    configurable: true
});

console.log("".isEmpty1()); // true
console.log("".isEmpty2()); // true

(Это также использует defineProperty, но это строгий режим, который имеет значение для значения this.)


Это очень редко для создания строковых объектов, и почти никогда не нужно делать это правильно.

1 голос
/ 25 мая 2020

НЕТ

попробуйте для

s1 = new String('');
s2 = []
s3 = {length: 0}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...