Почему typeof null "объект"?

Я читаю главу 4 "Профессиональный Javascript для веб-разработчиков", в которой говорится, что пять типов примитивов: неопределенные, нулевые, логические, числа и строки.

Если null примитив, почему typeof(null) вернуть "object"?

Разве это не значит, что null передается по ссылке (я предполагаю, что здесь все объекты передаются по ссылке), следовательно, делая его НЕ примитивным?

12 ответов

В первой реализации JavaScript значения JavaScript были представлены как тег типа и значение, причем тег типа для объектов был 0, а также null был представлен как NULL указатель (0x00 на большинстве платформ). В результате ноль 0 как тег типа, следовательно, фальшивая typeof возвращаемое значение ( ссылка).

 typeof null === 'object'; // This stands since the beginning of JavaScript

Для ECMAScript было предложено "исправить" (через подписку). Это привело бы к:

typeof null === 'null'

... но это изменение было отклонено из-за проблем с кодом, использующего эту специфическую "причуду" для проверки null,

Если null примитив, почему typeof(null) вернуть "object"?

Потому что в спецификации так сказано.

11.4.3 typeof оператор

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

  1. Пусть val будет результатом вычисления UnaryExpression.
  2. Если Тип (val) является Ссылкой, тогда
    а. Если IsUnresolvableReference (val) имеет значение true, вернуть " undefined ".
    б. Пусть val будет GetValue (val).
  3. Вернуть строку, определенную типом (val) в соответствии с таблицей 20.

Как уже указывалось, в спецификации так сказано. Но так как реализация JavaScript предшествовала написанию спецификации ECMAScript, и спецификация была осторожна, чтобы не исправить ошибки начальной реализации, все еще остается законный вопрос о том, почему это было сделано именно таким образом. Дуглас Крокфорд называет это ошибкой. Киро Риск считает, что это что-то вроде:

Причина этого заключается в том, что null, по сравнению с undefined, (был и остается) часто используется там, где появляются объекты. Другими словами, null часто используется для обозначения пустой ссылки на объект. Когда Брендан Эйх создал JavaScript, он придерживался той же парадигмы, и имело смысл (возможно) возвращать "объект". На самом деле спецификация ECMAScript определяет null в качестве примитивного значения, которое представляет собой намеренное отсутствие какого-либо значения объекта (ECMA-262, 11.4.11).

нулевой

// Это стоит с самого начала JavaScript
typeof null === 'object';

Короткий ответ:

Это ошибка первого выпуска ECMAScript , которую, к сожалению, нельзя исправить, поскольку это нарушит существующий код.

Объяснение:

Однако на самом деле есть одно логическое объяснение тому, почему null является объектом в javascript.

В начальной версии JavaScript значения хранились в 32-битных блоках , которые состояли из небольшого тега типа (1–3 бита) и фактических данных значения . Теги типа хранились в младших битах единиц. Их было пятеро:

      000: object. The data is a reference to an object.
1: int. The data is a 31 bit signed integer.
010: double. The data is a reference to a double floating point number.
100: string. The data is a reference to a string.
110: boolean. The data is a boolean.

Для всех объектов это было 000 как биты тега типа . null считался особым значением в JavaScript с самой первой его версии. null был представлением нулевого указателя . Однако в JavaScript, подобно C, не было указателей. Таким образом, null просто означал ничего или пустоту и представлялся всеми нулями . Следовательно, все его 32 бита были 0 . Поэтому всякий раз, когда интерпретатор JavaScrit читает null, он считает первые 3 бита типом «объект». Вот почему typeof null возвращает «объект».

Ресурс: https://2ality.com/2013/10/typeof-null.html#:~:text=In%20JavaScript%2C%20typeof%20null%20is,it%20would%20break%20existing%20code.

Примечание:

Было предложено исправление для ECMAScript (через подписку), но оно было отклонено.Это привело бы к

typeof null === 'ноль'.

Из книги YDKJS

Это давняя ошибка в JS, но она, вероятно, никогда не будет исправлена. Слишком много кода в Интернете зависит от ошибки, и, следовательно, ее исправление вызовет гораздо больше ошибок!

Если null примитив, почему typeof(null) вернуть "object"?

вкратце: это ошибка в ECMAScript, и тип должен быть null

ссылка: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/null

В JavaScript null - это "ничего". Предполагается, что этого не существует. К сожалению, в JavaScript тип данных null является объектом. Вы можете считать ошибкой JavaScript, что typeof null является объектом. Он должен быть нулевым.

В JavaScript typeof null - это 'object', что неверно предполагает, что null является объектом. Это ошибка, которую, к сожалению, нельзя исправить, поскольку она нарушит существующий код.

Спецификация ECMAScript определяет эти типы данных языка :

6.1.1 Не определено Тип
6.1.2 Null Тип
6.1.3 Логический тип
6.1.4 Строка Тип
6.1.5 Символ Тип
6.1.6 Числовые типы
    6.1.6.1 Номер Тип
    6.1.6.2 BigInt Тип
6.1.7 Тип объекта

По историческим причинам Оператор несовместим с этой категоризацией в двух случаях:

  • typeof null == "object": это прискорбно, но с этим приходится жить.
  • typeofобъекта функции оценивается как «функция», даже если согласно спецификации он имеет тип данных Object .

Другой оператор - instanceof- может использоваться, чтобы узнать, наследуется ли объект от определенного прототипа. Например, [1,2] instanceof Array будет оценивать как истину.

Один из способов определить, является ли значение объектом, - использовать Object функция:

      if (Object(value) === value) // then it is an object; i.e., a non-primitive

++Ответ автора:

Я думаю, что уже слишком поздно исправлять typeof. Изменение, предложенное для typeof null, нарушит существующий код.

Слишком поздно. С тех пор, как Microsoft создала свой собственный движок JavaScript и скопировала все функции и ошибки первой версии движка, все последующие движки скопировали эту ошибку, и теперь уже слишком поздно ее исправлять.

      JS_TypeOfValue(JSContext *cx, jsval v)
{
    JSType type = JSTYPE_VOID;
    JSObject *obj;
    JSObjectOps *ops;
    JSClass *clasp;

    CHECK_REQUEST(cx);
    if (JSVAL_IS_VOID(v)) {
        type = JSTYPE_VOID;
    } else if (JSVAL_IS_OBJECT(v)) {
        obj = JSVAL_TO_OBJECT(v);
        if (obj &&
            (ops = obj->map->ops,
                ops == &js_ObjectOps
                ? (clasp = OBJ_GET_CLASS(cx, obj),
                clasp->call || clasp == &js_FunctionClass)
                : ops->call != 0)) {
            type = JSTYPE_FUNCTION;
        } else {
            type = JSTYPE_OBJECT;
        }
    } else if (JSVAL_IS_NUMBER(v)) {
        type = JSTYPE_NUMBER;
    } else if (JSVAL_IS_STRING(v)) {
        type = JSTYPE_STRING;
    } else if (JSVAL_IS_BOOLEAN(v)) {
        type = JSTYPE_BOOLEAN;
    }
    return type;
}

Для людей, которым интересен какой-то код, который сделал такое поведение, это ссылка для вас, ребята....

почему typeof null является объектом с реализацией

Это остаток ошибки из первой версии javascript.

«Это ошибка, которую, к сожалению, нельзя исправить, потому что это нарушит существующий код».

Ссылка и дополнительная информация: https://2ality.com/2013/10/typeof-null.html

Другие вопросы по тегам