programing

spread 연산자 vs array.concat()

instargram 2023. 2. 26. 09:02
반응형

spread 연산자 vs array.concat()

와의 차이는 무엇입니까?spread operator그리고.array.concat()

let parts = ['four', 'five'];
let numbers = ['one', 'two', 'three'];
console.log([...numbers, ...parts]);

Array.concat()기능.

let parts = ['four', 'five'];
let numbers = ['one', 'two', 'three'];
console.log(numbers.concat(parts));

두 결과 모두 동일합니다.그럼 어떤 시나리오를 사용할까요?그리고 어떤 것이 퍼포먼스에 가장 적합할까요?

concat인수가 배열이 아닐 경우 스프레드는 매우 다릅니다.

인수가 배열이 아닌 경우concat를 전체적으로 추가하는 한편,...반복하려다 실패하면 실패하게 됩니다.고려사항:

a = [1, 2, 3]
x = 'hello';

console.log(a.concat(x));  // [ 1, 2, 3, 'hello' ]
console.log([...a, ...x]); // [ 1, 2, 3, 'h', 'e', 'l', 'l', 'o' ]

여기서,concat는 스트링을 원자적으로 처리합니다....는 기본 반복기 char-by-char를 사용합니다.

또 다른 예는 다음과 같습니다.

x = 99;

console.log(a.concat(x));   // [1, 2, 3, 99]
console.log([...a, ...x]);  // TypeError: x is not iterable

다시 한 번 말씀드리지만concat숫자는 원자이고,...반복하려다 실패한다.

마지막으로:

function* gen() { yield *'abc' }

console.log(a.concat(gen()));   // [ 1, 2, 3, Object [Generator] {} ]
console.log([...a, ...gen()]);  // [ 1, 2, 3, 'a', 'b', 'c' ]

concat는 제너레이터를 반복하지 않고 전체적으로 부가합니다....모든 가치를 멋지게 끌어냅니다.

요약하자면, 당신의 주장이 아마도 논리가 아닐 때,concat그리고....반복할지 여부에 따라 달라집니다.

위는 디폴트 동작에 대해 설명합니다.concat단, ES6에서는 로 덮어쓸 수 있습니다.기본적으로 이 기호는 다음과 같습니다.true어레이의 경우 및false다른 모든 것에 대해서요.로 설정true말한다concat주장을 반복하다...다음 작업을 수행합니다.

str = 'hello'
console.log([1,2,3].concat(str)) // [1,2,3, 'hello']

str = new String('hello');
str[Symbol.isConcatSpreadable] = true;
console.log([1,2,3].concat(str)) // [ 1, 2, 3, 'h', 'e', 'l', 'l', 'o' ]

퍼포먼스 측면concat어레이 고유의 최적화를 통해 이점을 얻을 수 있기 때문에 고속화됩니다....공통 반복 프로토콜을 준수해야 합니다.타이밍:

let big = (new Array(1e5)).fill(99);
let i, x;

console.time('concat-big');
for(i = 0; i < 1e2; i++) x = [].concat(big)
console.timeEnd('concat-big');

console.time('spread-big');
for(i = 0; i < 1e2; i++) x = [...big]
console.timeEnd('spread-big');


let a = (new Array(1e3)).fill(99);
let b = (new Array(1e3)).fill(99);
let c = (new Array(1e3)).fill(99);
let d = (new Array(1e3)).fill(99);

console.time('concat-many');
for(i = 0; i < 1e2; i++) x = [1,2,3].concat(a, b, c, d)
console.timeEnd('concat-many');

console.time('spread-many');
for(i = 0; i < 1e2; i++) x = [1,2,3, ...a, ...b, ...c, ...d]
console.timeEnd('spread-many');

음.console.log(['one', 'two', 'three', 'four', 'five'])같은 결과를 얻을 수 있는데 왜 여기서 둘 중 하나를 사용합니까? :P

일반적으로는concat임의의 소스에서 2개 이상의 어레이가 있는 경우 항상 어레이의 일부인 추가 요소가 이전에 알려진 경우 어레이 리터럴에서 확산 구문을 사용합니다.예를 들어 어레이 리터럴과concat당신의 코드에서 구문을 퍼뜨리고concat그렇지 않은 경우:

[...a, ...b] // bad :-(
a.concat(b) // good :-)

[x, y].concat(a) // bad :-(
[x, y, ...a]    // good :-)

또한 두 가지 대안은 배열이 아닌 값을 처리할 때 상당히 다르게 동작합니다.

이미 시나리오에 대한 좋은 답변이 있기 때문에 퍼포먼스 질문만 답변드립니다.테스트를 작성하여 최신 브라우저에서 실행하였습니다.결과 및 코드 아래에 있습니다.

/*
 * Performance results.
 * Browser           Spread syntax      concat method
 * --------------------------------------------------
 * Chrome 75         626.43ms           235.13ms
 * Firefox 68        928.40ms           821.30ms
 * Safari 12         165.44ms           152.04ms
 * Edge 18           1784.72ms          703.41ms
 * Opera 62          590.10ms           213.45ms
 * --------------------------------------------------
*/

내가 작성해서 사용한 코드 아래.

const array1 = [];
const array2 = [];
const mergeCount = 50;
let spreadTime = 0;
let concatTime = 0;

// Used to popolate the arrays to merge with 10.000.000 elements.
for (let i = 0; i < 10000000; ++i) {
    array1.push(i);
    array2.push(i);
}

// The spread syntax performance test.
for (let i = 0; i < mergeCount; ++i) {
    const startTime = performance.now();
    const array3 = [ ...array1, ...array2 ];

    spreadTime += performance.now() - startTime;
}

// The concat performance test.
for (let i = 0; i < mergeCount; ++i) {
    const startTime = performance.now();
    const array3 = array1.concat(array2);

    concatTime += performance.now() - startTime;
}

console.log(spreadTime / mergeCount);
console.log(concatTime / mergeCount);

유효하다고 생각되는 한 가지 차이는 큰 어레이 크기에 대해 확산 연산자를 사용하면 다음 오류가 발생한다는 것입니다.Maximum call stack size exceeded 될 것 같아요.concat환입니니다다

var  someArray = new Array(600000);
var newArray = [];
var tempArray = [];


someArray.fill("foo");

try {
  newArray.push(...someArray);
} catch (e) {
  console.log("Using spread operator:", e.message)
}

tempArray = newArray.concat(someArray);
console.log("Using concat function:", tempArray.length)

가 하나 요.concat ★★★★★★★★★★★★★★★★★」push즉, 전자는 기본 어레이를 변환하지 않으므로 결과를 동일 또는 다른 어레이에 할당해야 합니다.

let things = ['a', 'b', 'c'];
let moreThings = ['d', 'e'];
things.concat(moreThings);
console.log(things); // [ 'a', 'b', 'c' ]
things.push(...moreThings);
console.log(things); // [ 'a', 'b', 'c', 'd', 'e' ]

버그를 본 적이 있습니다.concat을 사용법

업데이트:

은 콩캣보다 .spread다음 벤치마크에서는 소규모 어레이와 대규모 어레이가 모두 참가하고 있습니다.https://jsbench.me/nyla6xchf4/1

여기에 이미지 설명 입력

// preparation
const a = Array.from({length: 1000}).map((_, i)=>`${i}`);
const b = Array.from({length: 2000}).map((_, i)=>`${i}`);
const aSmall = ['a', 'b', 'c', 'd'];
const bSmall = ['e', 'f', 'g', 'h', 'i'];

const c = [...a, ...b];
// vs
const c = a.concat(b);

const c = [...aSmall, ...bSmall];
// vs
const c = aSmall.concat(bSmall)

이전 버전:

대규모 어레이의 퍼포먼스에 대해서는, 몇개의 회답이 맞지만, 소규모 어레이의 경우는 퍼포먼스가 크게 다릅니다.

결과는 https://jsperf.com/spread-vs-concat-size-agnostic에서 확인할 수 있습니다.

바와 같이 확산가 50% 빨라집니다. 시시, 、 %%%%%%% 50% 。concat이치노

비교에 도움이 되는 것은 @georg의 대답입니다.또한 실행 시 .flat()이 어떻게 비교될지 궁금했는데, 이는 단연 최악이었습니다.속도가 우선인 경우 .flat()을 사용하지 마십시오.(그동안 몰랐던 것)

  let big = new Array(1e5).fill(99);
  let i, x;

  console.time("concat-big");
  for (i = 0; i < 1e2; i++) x = [].concat(big);
  console.timeEnd("concat-big");

  console.time("spread-big");
  for (i = 0; i < 1e2; i++) x = [...big];
  console.timeEnd("spread-big");

  console.time("flat-big");
  for (i = 0; i < 1e2; i++) x = [[], big].flat();
  console.timeEnd("flat-big");

  let a = new Array(1e3).fill(99);
  let b = new Array(1e3).fill(99);
  let c = new Array(1e3).fill(99);
  let d = new Array(1e3).fill(99);

  console.time("concat-many");
  for (i = 0; i < 1e2; i++) x = [1, 2, 3].concat(a, b, c, d);
  console.timeEnd("concat-many");

  console.time("spread-many");
  for (i = 0; i < 1e2; i++) x = [1, 2, 3, ...a, ...b, ...c, ...d];
  console.timeEnd("spread-many");

  console.time("flat-many");
  for (i = 0; i < 1e2; i++) x = [1, 2, 3, a, b, c, d].flat();
  console.timeEnd("flat-many");

언급URL : https://stackoverflow.com/questions/48865710/spread-operator-vs-array-concat

반응형