Как внешний интерфейс изящно обрабатывает массивоподобные объекты?

JavaScript
Как внешний интерфейс изящно обрабатывает массивоподобные объекты?

1. Введение

Недавно в отдел Лео пришел фронтенд-стажер Робин, который, будучи мастером, подробно ознакомил Робина с бизнесом компании, работой отдела и т. д., а также с картой обучения фронтенд-новичков. Затем Робин начнет счастливую неделю обучения~ Неделю спустя Лео устроил Робину экзаменационные задания и разработал страницу для поиска и выбора.Эффект примерно такой:

Увидев эту визуализацию, Робин выглядела самодовольной, это действительно не сложно~

Через несколько дней Робин показала Лео свой код с написанным ею кодом и в замешательстве спросила:

Она выводит этот «массив» в консоль:

Лев посмотрел на код:

getUserList(){
   const memberList = $('#MemberList li');
   memberList.map(item => { console.log(item) });
   console.log(memberList);
}

Лео снова спросил:

Робин выглядел озадаченным, а затем Лео добавил:Array.fromМетоды, как показано ниже:

getUserList(){
    const memberList = Array.from($('#MemberList li'));
    memberList.map(item => {
        console.log(item)
    })
    console.log(memberList)
}

Затем повторно выполните код и выведите следующий результат:

Результат выхода Лео, говорит Робин:

Робин выжидающе посмотрел на мастера, дамассивоподобный объектбольше надежды.

Во-вторых, введение массивоподобных объектов

2.1 Введение концепции

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

Например 🌰:

const arrLike = {
  0: 'name',
  1: 'age',
  2: 'job',
  length: 3
}

2.2 Общие массивоподобные объекты

  • argumentsобъект;
function f() {
  return arguments;
}
f(1,2,3)

// Arguments(3) [1, 2, 3, callee: ƒ, Symbol(Symbol.iterator): ƒ]
  • NodeList(Напримерdocument.getElementsByClassName('a')Полученные результаты;
document.getElementsByTagName('img')
// HTMLCollection(3) [img, img, img]
  • typedArray(НапримерInt32Array);

типизированный массив, т.е.Объекты типизированного массивапредставляет собой массивоподобный объект, предоставляющий механизм доступа к необработанным двоичным данным. Движок JavaScript выполняет некоторые внутренние оптимизации, чтобы операции с массивами могли быть быстрыми. Однако по мере того, как веб-приложения становятся все более и более мощными, особенно с новыми дополнениями, такими как редактирование аудио и видео, доступ к необработанным данным из веб-сокетов и т. д., становится ясно, что иногда, если вы используете код JavaScript, вы можете быстро и легко использовать типизированные массивы. , Манипулирование необработанными двоичными данными будет очень полезно. ——"Типизированные массивы MDN"

const typedArray = new Uint8Array([1, 2, 3, 4])
// Uint8Array(4) [1, 2, 3, 4]

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

$('img')
// init(3) [img, img, img, prevObject: init(1), context: document, selector: "img"]

Конечно, есть и некоторые необычные массивоподобные объекты, такие как «результаты, возвращаемые Storage API», которые здесь не перечислены.

3. Массивоподобные свойства объекта

В следующем коде Робина в качестве примера представлены свойства массивоподобных объектов:

const memberList = $('#MemberList li');

3.1 Читать и писать

// 读取
memberList[0];
// Node: <li>...</li>

// 写入
memberList[0] = document.createElement("div")
memberList[0];
//  Node: <div>...</div>

3.2 Длина

memberList.length; 
// 10

3.3 Traversal

for (let i = 0;i < memberList.length; i++){
    console.log(memberList[i]);
}

/*
	Node: <li>...</li>
	Node: <li>...</li>
  ... 共10个,省略其他
*/

memberList.map(item => console.log(item));

/*
	0
  ... 共10个,省略其他
*/

Но если этоHTMLCollectionнельзя использоватьmapНемного:

const img = document.getElementsByTagName("img");
img.map(item => console.log(item));

// Uncaught TypeError: img.map is not a function

В-четвертых, массивоподобная обработка объектов

Лео смотрит на код Робина для обработки этого списка:

getUserList(){
    const memberList = $('#MemberList li');
    const result = {
        text: [],
        dom : [],
    };
    memberList.map(item => {
        item = memberList[item]
        // 判断当前节点是否有 checked 类名
    })
    console.log(result)
    this.showToast(`选中成员:${result.text}`);
}

Очевидно, Робин не понял того, что получил jQuery.memberListВыполните обработку, используйте ее напрямую и получите соответствующее значение через индекс. Лео представил Робин:

4.1 Array.from

использоватьArray.fromЧтобы преобразовать подобный массиву объект в массив, операция очень проста:

getUserList(){
    const memberList = Array.from($('#MemberList li'));
    // 省略其他代码
}

Этограмматикаследующим образом:

Array.from(arrayLike[, mapFn[, thisArg]])

параметр:

  1. arrayLikeОбъект псевдомассива или итерируемый объект, который вы хотите преобразовать в массив.
  2. mapFnнеобязательный Если этот параметр указан, функция обратного вызова будет выполняться для каждого элемента в новом массиве.
  3. thisArgНеобязательный необязательный параметр, выполнить функцию обратного вызоваmapFnВремяthisобъект.

возвращаемое значение: Новый экземпляр массива.

Более Array.from Введение можно посмотреть в документации.

4.2 Array.prototype.slice.call()

slice()метод возвращает новый объект массива, который являетсяbeginа такжеendОпределяется исходным массивоммелкая копия(включатьbegin, исключаяend).Исходный массив не будет изменен.

Код реализации:

getUserList(){
    const memberList = Array.prototype.slice.call($('#MemberList li'));
    // 省略其他代码
}

БолееArray.prototype.sliceВведение можно посмотреть в документации.

4.3 Оператор спреда ES6

Синтаксис спреда (синтаксис спреда), может использоваться при построении вызова функции/массива,Расширение выражений массива или строк на синтаксическом уровне; при построении литерального объекта выражение объекта также может бытьkey-valueспособ расшириться.

Код реализации:

getUserList(){
    const memberList = [...document.getElementsByTagName("li")];
    // 省略其他代码
}

БолееОператор спреда ES6Введение можно посмотреть в документации.

4.4 Использование concat+apply

getUserList(){
    const memberList = Array.prototype.concat.apply([], $('#MemberList li'));
    // 省略其他代码
}

V. Резюме дела

После того, как Лео представил это знание, Робин оптимизировал собственный код, включивк массивоподобным объектамОсновной код js выглядит следующим образом:

class SelectMember {
    constructor(){
        this.MockUsers = window.MockUsers;
        this.init();
    }
    init(){
        this.initMemberList('#MemberList', this.MockUsers);
        this.initBindEvent();
    }
	  // ... 省略部分代码,保留核心代码
    submitSelect(){
        const memberList = Array.from($('#MemberList li'));
        const result = {
            text: [],
            dom : [],
        };
        memberList.map(item => {
            const hasClass = $(item).children('.round-checkbox').children('span').hasClass(this.selectClassName);
            if(hasClass){
                result.text.push($(item).children('.user-data').children('h4').text());
                result.dom.push(item);
            }
        })
        this.showToast(`选中成员:${result.text}`);
    }
}

let newMember = new SelectMember();

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

Полный код всего проекта можно найти по адресумой вид на гитхабе:

GitHub.com/Ping An8787/…

6. Резюме

В этой статье мы познакомим вас с использованием массивоподобных объектов в реальной разработке с помощью практического сценария.Для обычных массивоподобных объектов мы также представляем методы обработки, которые могут значительно сократить наши операции с массивоподобными объектами. массив, более удобный для работы с данными. Я надеюсь, что после прочтения этой статьи вы больше не будете сбиты с толку, когда в будущем столкнетесь с массивоподобными объектами~~~