Почему [].slice.call() возвращает «пустые слоты»?

Я пытаюсь обернуть сложный объект массивом длины 1 (т. е. объект является единственным элементом массива) и надеюсь сделать это в конструкторе класса. . . Чтобы добраться туда, я играл с [].slice.call(), и когда я играл в целях тестирования, я попробовал следующее в консоли:

foo = {"a":{"a1":1},"b":{"b1":2},length: 2};
[].slice.call(foo);

Я получил массив длины два с «двумя пустыми слотами».

Учитывая, что [].slice.call({"a": 1, "b": 2, length: 2} дал [1, 2], я ожидал получить массив длины два следующим образом: [{"a1":1},{"b1":2}], вместо "два пустых слота". Работает ли [].slice.call только с «одномерными» объектами или происходит что-то еще? Заранее большое спасибо, если кто-то может пояснить!

Given that [].slice.call({"a": 1, "b": 2, length: 2} yielded [1, 2] Не могу воспроизвести. Я получаю (2) [empty × 2]
CertainPerformance 31.03.2019 06:56

Моя вина! Я упрощал и в итоге переупростил. . . На самом деле это [].slice.call({"0": "a", "1": b, length 2}) произвело ["a", "b"] . . . так что я предполагаю, что объект, который нарезается, должен предоставить indices как keys, чтобы [].slice.call() работал?

Crowdpleasr 31.03.2019 07:03
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
2
85
2

Ответы 2

slice будет перебирать только свойства числовой индекс объекта. См. спец.:

  1. Let relativeStart be ToInteger(start).

(поэтому, если start — это undefined, например, когда slice вызывается без аргументов, relativeStart — это 0)

Затем он будет перебирать числовые индексы от relativeStart (или 0, если relativeStart отрицательно) до значения свойства length объекта:

  1. If relativeStart is negative, let k be max((len + relativeStart),0); else let k be min(relativeStart, len).

8. If relativeEnd is negative, let final be max((len + relativeEnd),0); else let final be min(relativeEnd, len).

10. Repeat, while k < final

  • (push obj[k] into the new array-like object being created)

Так:

Does [].slice.call only work on "one-dimensional" objects, or is there something else going on?

Он будет работать только с объектами с числовые свойства. Если у вас есть нечисловые свойства, они не будут повторяться с помощью slice.

Если вы хотите

wrap a complicated object in an array of length 1 (i.e., the object is the only entry in the array)

затем просто используйте [foo], например:

const foo = {"a":{"a1":1},"b":{"b1":2},length: 2};
const wrappedFoo = [foo];
console.info(wrappedFoo);

Is there an "easy" way to turn {"a":{"a1":"foo"},"b":{"b1":"bar"}} into [{"a1":"foo"},{"b1":"bar"}]?

Используйте Object.values для извлечения значений объекта в массив:

const obj = {"a":{"a1":"foo"},"b":{"b1":"bar"}};
const arr = Object.values(obj);
console.info(arr);

Фантастика, и большое спасибо. Что, если я нахожусь в конструкторе и пытаюсь использовать значения по умолчанию для параметров, чтобы заполнить свойства класса. . . сказать, что у меня есть: constructor( public authData = { "prop1": {"key1": 3}, "prop2": {"key1": 4} } . . . но вместо {"key1": 4} я хочу [{"key1": 4}]?

Crowdpleasr 31.03.2019 07:12

Возьмите Object.values объекта, а затем используйте .map, чтобы окружить каждый массив, например .map(arr => [arr])

CertainPerformance 31.03.2019 07:21

Большое спасибо. Это очень полезно. Я поиграю с этим завтра, чтобы подтвердить. Очень ценится!

Crowdpleasr 31.03.2019 07:25

object, который вы используете в качестве аргумента call(), передается как аргумент thisslice(), и он будет работать только с числовыми свойствами объекта, как уже упоминалось Определенная производительность. Если вы используете числовые свойства, это будет работать так, как вы ожидаете:

let foo1 = {"0": 1, "1": 2, length: 2};
console.info([].slice.call(foo1));

let foo2 = {"0": {"a1":1}, "1": {"b1":2}, length: 2};
console.info([].slice.call(foo2));
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}

Однако это редкий способ получить то, что уже дает вам Объект.значения():

let foo1 = {"0": 1, "1": 2};
console.info(Object.values(foo1));

let foo2 = {"0": {"a1":1}, "1": {"b1":2}};
console.info(Object.values(foo2));
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}

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