Tesseractjh
한 걸음씩
Tesseractjh
전체 방문자
오늘
어제
  • 전체 (293)
    • IT (30)
      • JavaScript (7)
      • TypeScript (5)
      • React (5)
      • Next.js (3)
      • MongoDB (2)
      • Webpack (2)
      • HTML & CSS (1)
      • Git (0)
      • AWS (1)
      • 기타 (4)
    • 연습장 (259)
      • 백준(BOJ) 문제풀이 (185)
      • 프로그래머스 문제풀이 (61)
      • LeetCode 문제풀이 (2)
      • HackerRank 문제풀이 (7)
      • 낙서장 (3)
      • 기타 (1)
    • 프로젝트 (3)
      • 지뢰피하기 (1)
      • 키릴-라틴 문자 변환기 (1)
      • Flex & Grid (1)
    • 멋쟁이사자처럼 프론트엔드 스쿨 1기 (1)
      • 일기 & 회고록 (1)

인기 글

티스토리

hELLO · Designed By 정상우.
Tesseractjh

한 걸음씩

[JS] 함수의 매개변수와 RangeError
IT/JavaScript

[JS] 함수의 매개변수와 RangeError

2021. 7. 23. 16:40

함수가 호출되면 함수의 매개변수, 반환 주소값, 지역 변수 등의 스택 프레임(Stack Frame)이 호출 스택(Call Stack)에 쌓이게 된다. 재귀함수나 콜백함수에 의해서 함수가 종료되지 않고 너무 많이 호출되면 이러한 스택 프레임들이 호출 스택의 메모리를 초과하게 되면 스택 오버플로우(Stack Overflow)가 발생한다.

 

함수의 호출이 너무 많아서 스택 오버플로우가 일어날 수도 있지만, 함수를 한 번만 호출했는데 매개변수가 너무 많아서 스택 오버플로우가 발생할 수도 있다. 함수의 매개변수도 호출 스택에 쌓이기 때문이다.

 

const arr = new Array(1000000);
const arr2 = [...arr];

위의 코드에서 length가 1000000인 배열 arr를 스프레드 연산자(...)를 활용하여 arr2에 복사하였다.

그러나 위 코드를 아래와 같이 바꾸면 RangeError가 발생한다.

const arr = new Array(1000000);
const arr2 = [];
arr2.push(...arr); // Uncaught RangeError: Maximum call stack size exceeded

push라는 함수의 매개변수로 인수를 1,000,000개나 전달했기 때문이다.

const doNothing = function (...args) {};
const arr = new Array(1000000);
doNothing(...arr); // Uncaught RangeError: Maximum call stack size exceeded

Rest 파라미터(나머지 매개변수)를 사용하면 가변 인자 함수를 만들 수 있는데, 이 경우에 너무 많은 인수를 넣어 함수를 호출하면 스택 오버플로우가 발생하게 된다.

const doNothing = function (...args) {};
const arr = new Array(1000000);
doNothing.apply(null, arr); // Uncaught RangeError: Maximum call stack size exceeded

인수 리스트를 배열이나 유사 배열 객체(array-like objects)로 받아 함수에게 전달하는 Function.prototype.apply 또한 너무 많은 인수를 전달하면 동일한 문제가 발생한다.

 

 

스택 오버플로우를 피하기 위해서는 "한 번에" 너무 많은 인수를 전달하지 않으면 된다.

const arr = new Array(1000000);
const arr2 = [];
for (const i of arr) arr2.push(i);
// 또는 그냥 arr2 = [...arr]
const arr = new Array(1000000).fill(1);
arr[12345] = 2;
// const maxNum = Math.max(...arr)
// Uncaught RangeError: Maximum call stack size exceeded
const maxNum = arr.reduce((acc, v) => Math.max(acc, v), arr[0]); // 2

 

 

참조


https://stackoverflow.com/questions/63705432/maximum-call-stack-size-exceeded-when-using-the-dots-operator?rq=1 

http://net-informations.com/js/err/range.htm

https://github.com/nodejs/node/issues/16870

http://tcpschool.com/c/c_memory_stackframe

저작자표시 비영리 (새창열림)

'IT > JavaScript' 카테고리의 다른 글

[JS] 자바스크립트로 엑셀 파일(xlsx) 만들어서 다운받기  (0) 2022.08.05
[JS] Invalid regular expression: invalid group specifier name  (0) 2022.06.21
[JS] Selection API로 선택된 텍스트 정보 가져오기  (0) 2022.06.01
[JS] 자바스크립트의 배열 생성 방법  (0) 2021.07.29
Node.js로 백준(BOJ) 문제 풀 때 유의할 점들  (12) 2021.04.10
    'IT/JavaScript' 카테고리의 다른 글
    • [JS] Invalid regular expression: invalid group specifier name
    • [JS] Selection API로 선택된 텍스트 정보 가져오기
    • [JS] 자바스크립트의 배열 생성 방법
    • Node.js로 백준(BOJ) 문제 풀 때 유의할 점들
    Tesseractjh
    Tesseractjh
    바닐라 자바스크립트를 좋아하는 개발자입니다

    티스토리툴바