Почему метод javascript isArray () в этом примере возвращает true, если массив был переопределен как стандартный объект? - PullRequest
0 голосов
/ 01 декабря 2018

Я пытаюсь изучить Javascript - вот моя проблема:

В примерах w3schools.com javascript они показывают следующий пример:

    var person = [];
    person["firstName"] = "John";
    person["lastName"] = "Doe";
    person["age"] = 46; 
    document.getElementById("demo").innerHTML =
    person[0] + " " + person.length;

Определен массив person, но затем они продолжают добавлять некоторые элементы с именованным индексом.Затем пытается напечатать в HTML-документе 0-й элемент и количество элементов массива, как если бы вы использовали стандартный массив.

В описании говорится:

Если вы используетеименованный индекс при доступе к массиву, JavaScript переопределит массив к стандартному объекту, а некоторые методы и свойства массива будут давать неопределенные или неправильные результаты.

Фактически, person [0] и person.возвращаемая длина соответственно "undefined" и "0".Даже если person изначально был определен как массив, вставляя новые именованные элементы indexes, массив должен быть переопределен как объект.Но когда я пытаюсь использовать метод Array.isArray () для проверки, он возвращает true:

var person = [];
person["firstName"] = "John";
person["lastName"] = "Doe";
person["age"] = 46; 
document.getElementById("demo").innerHTML =
person[0] + " " + person.length;

document.getElementById('test').innerHTML = Array.isArray(person);// returns true

Итак, почему?если, как указано в учебном пособии, это было эффективно переопределено как стандартный объект, и ECMAScript 5 добавил метод .isArray () для проверки, является ли что-то массивом и ничем иным, не должно ли это возвращать false, инстинкт true?

Я уверен, что что-то пропустил.Если я определяю человека следующим образом:

person = {};

, тогда он возвращает false, как и ожидалось.Что здесь происходит?Я просто хотел понять массивы немного больше, это меня смущает.Это просто битый массив, но все же массив?

Вот пример (без бита Array.isarray (), просто по умолчанию): https://www.w3schools.com/js/tryit.asp?filename=tryjs_array_associative_2

Ответы [ 3 ]

0 голосов
/ 01 декабря 2018

Прежде всего я хочу отметить, что пример, который вы взяли со страницы w3schools для массивов , взят из раздела «Ассоциативные массивы», в котором есть это важное введение:

Многие языки программирования поддерживают массивы с именованными индексами.
Массивы с именованными индексами называются ассоциативными массивами (или хэшами).
JavaScript поддерживает , а не поддерживает массивы с именованными индексами.
В JavaScript, массивы всегда используют пронумерованные индексы .

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

Массив становится объектом?

То, что JavaScript все еще считает переменную массивом, является ожидаемым.Он становится массивом в момент присвоения [], и это не меняет , добавляя свойства к этому объекту.Да, массивы являются объектами.У них просто есть дополнительные возможности.

Массив не потерял ни одной из своих массивоподобных возможностей, но эти функции просто не работают с этими строковыми свойствами, а только с числовыми (точнее,целые неотрицательные).

Вы свободно цитировали следующее утверждение из w3schools:

Если вы используете именованные индексы, JavaScript переопределит массив в стандартный объект.

Это неверная информация и ведет к вашему недоразумению.Переопределения не происходит.Когда вы добавляете свойства к любому объекту, объект не меняет «тип».Он остается экземпляром того, что было раньше ... Массив остается массивом, объект даты остается датой, объект регулярного выражения остается регулярным выражением, даже если вы назначаете ему другие свойства.Но нечисловые свойства не «учитываются» для массива: длина будет оставаться неизменной при добавлении таких свойств.Длина только показывает что-то о числовых свойствах объекта.

Эта цитата является еще одной иллюстрацией того, что сообщество JavaScript думает о w3schools.com, то есть, что оно не самое надежноессылка, даже если она имеет значение для изучения языка.

Пример добавления полезных свойств к массивам

Сказав выше, есть случаи, когда вы можете намеренно использовать такиесвойства на массивах.Давайте, например, подумаем о массиве слов, который сортируется:

const arr = ["apple", "banana", "grapefruit", "orange", "pear"];

Теперь давайте добавим что-то в этот массив, который будет обозначать, что он в данный момент отсортирован:

arr.isSorted = true;

Мы могли бы представитьфункция, которая позволит добавить значение в этот массив, но также проверяет, отсортирован ли массив:

function addFruit(arr, fruit) {
    if (arr.length && fruit < arr[arr.length-1]) {
        arr.sorted = false;
    }
    arr.push(fruit);
}

Затем, после добавления нескольких значений, было бы интересно проверить, является ли массивнужна сортировка:

if (!arr.sorted) arr.sort();

Так что это дополнительное свойство помогает избежать выполнения ненужной сортировки.Но в остальном массив обладает всеми функциями, как если бы у него не было этого дополнительного свойства.

0 голосов
/ 01 декабря 2018

Я думаю, что реализация isArray () в виде полифилла в некоторой степени очистит ваше сомнение. # Polyfill

0 голосов
/ 01 декабря 2018

Объект, который устанавливается как массив и затем заполняется как объект, становится членом обоих классов.Методы класса Array будут применяться к его «массиву»:

Array.isArray(person);

возвращает true.Методы класса Object будут применяться к его объектному объекту:

typeof(person);

возвращает object.Когда это может быть один из них, 'array-ness' будет преобладать, потому что переменная была сначала определена как массив:

console.log(person);

поместит Array [ ] на консоль, потому что она запускает класс Arrayметод ведения журнала.Он отображается как пустой массив, так как у него нет нумерованных элементов, но вы можете добавить некоторые:

person[2]=66;

, и тогда console.log будет записывать Array [ <2 empty slots>, 66 ].

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...