27 min to read
배열(array)
배열(Array)
다수의 항목을 저장하는 기본 데이터 구조 역할. 배열 내 포함된 개별 항목을 요소라 하며, 숫자, 문자열, 객체 등을 포함한 다양한 범위의 데이터 유형을 포괄함.
예시1: [ ] 표기법을 사용하면 미리 정의된 값으로 배열을 인스턴스화하거나 후속 초기화를 위해 비워 둘 수 있습니다.
예시2: 배열 내의 요소는 해당 인덱스 번호를 참조하여 액세스할 수 있습니다. 인덱스는 배열 내의 요소 위치에 대한 식별자 역할을 하며 번호 지정 규칙은 0부터 시작합니다.
let myArray = [1, 2, 3, 4, 5];
console.log(myArray[0]); // 1
console.log(myArray[1]); // 2
let myArray = [1, 2, 3, 4, 5];
myArray[2] = 30;
console.log(myArray); // [1, 2, 30, 4, 5]
JS 배열 조작용 메서드: ‘push()’, ‘pop()’, ‘shift()’, ‘unshift()’, ‘slice()’, ‘splice()’, ‘sort()’ 등이 있음. ‘reverse()’, ‘concat()’, ‘join()’, ‘map()’, ‘filter()’ 및 ‘reduce()’. 이러한 메소드는 배열 요소의 추가, 제거, 정렬 및 조작을 용이하게 하는 목적으로 사용함.
배열 생성
다양한 접근 방식으로 배열 생성이 가능함.
일반적인 방법은 []
표기법을 활용.
Array
생성자 또는 Array.of()
메서드를 사용해 배열 생성도 가능함.
예시1:
[]
표기법
let myArray = [1, 2, 3, 4, 5]; // 숫자 배열
let myStringArray = ["apple", "banana", "orange"]; // 문자 배열
let myOjectArray = [{name: "John", age: 30}, {name: "Jane", age: 25}] // 객체 배열
예시2: 배열 생성자 사용
let myArray = new Array(1, 2, 3, 4, 5); // 숫자 배열
let myStringArray = new Array("apple", "banana", "orange") // 문자 배열 생성
예시3:
Array.of()
메서드 사용
let myArray = Array.of(1, 2, 3, 4, 5); // 숫자 배열
let myStringArray = Array.of("apple", "banana", "oragne"); // 문자 배열
Array
생성자를 사용한 배열의 길이는 전달된 인수의 수에 따라 결정되며 인수가 제공되지 않는 경우 배열의 길이는 0이 됨.
배열 규칙
[]
표기법 사용.Array
생성자,Array.of()
메서드 사용.Array
생성자,Array.of()
메서드의 차이점을 이해:Array
생성자는 주어진 길이의 배열을 생성하지만Array.of()
는 주어진 요소로 배열 생성.- 배열 크기에 주의할 것, 대규모 배열은 메모리 및 성능 문제를 야기할 수 있음.
- 데이터 유형 지정: 배열에 저장하려는 데이터 유형을 지정할 것.
- 고유한 이름 사용: 충돌 방지
- 배열을 체계적으로 유지: 올바른 인덱싱으로 정리되었는가 확인.
- 불필요한 글로벌 스코프를 사용하지 말것: 스코프 오염이 발생할 수 있기 때문에 로컬 스코프로 할 것.
요소 접근법
배열 내 요소는 특정 위치의 개별 값을 의미함. 첫 번째 요소 인덱스는 0, 두 번째는 1임. 각 요소에 대해 0부터 1씩 증가함.
요소 접근 규칙
- 요소 인덱스가 []안에 지정되는 [] 표기법 사용.
- 1번째 요소는 인덱스 0, 2번째는 1.
- 음수 인덱스는 배열 끝의 요소에 접근할 수 있음.
- 변수를 사용해 인덱스를 지정 가능
- 존재하지 않는 인덱스 요소에 접근하면 “undefined” 가 표시됨.
- 정수가 아닌 값을 사용해 요소에 엑세스 하면 “TypeError” 발생.
- 배열 메서드
.slice()
사용시 배열 일부 복사본을 새 배열로 가져옴. - 배열 메서드
.splice()
사용시 배열 내 요소를 추가제거 가능.
예1: 배열의 1번째 요소 접근법
let fruits = ["apple", "banana", "orange"];
console.log(fruit[0]); // output : "apple"
예2: 배열의 마지막 요소 접근법
let fruits = ["apple", "banana", "orange"];
console.log(fruits[fruit.length -1]); // output : "orange"
예3: 변수를 인덱스로 사용
let fruits = ["apple", "banana", "orange"];
let index = 1;
console.log(fruit[index]); // output : "banana"
예4: 음수 인덱스 사용해 마지막 요소 엑세스
let fruits = ["apple", "banana", "orange"];
console.log(fruit[-1]); // output : "orange"
예5:
.slice()
메서드 사용. 일부 복사본 얻기.
- 추출 시작 인덱스
- 추출 종료 인덱스(결과에 미포함)
let fruits = ["apple", "banana", "orange"];
let subArray = fruits.slice(1,3);
console.log(subArray); // output : ["banana", "orange"]
예6:
.splice()
메서드는 배열 내 요소를 추가하거나 제거
let fruits = ["apple", "banana", "orange"];
fruits.splice(1, 1);
console.log(fruits); // output: ["apple", "orange"]
요소 업데이트
- 인덱스를 사용해 원하는 요소에 엑세스하고
=
연산자를 사용해 새 값을 할당할 수 있음.let myArray = [1, 2, 3, 4, 5]; myArray[2] = 30; console.log(myArray); // [1, 2, 30, 4, 5]
- ‘pop()’, ‘shift()’, ‘splice()’, ‘sort()’, ‘reverse()’, ‘concat()’, ‘fill()’, ‘ copyWithin()’, ‘map()’, ‘filter()’ 및 ‘reduce()’을 사용하면 조작할 수 있음.
let myArray = [1, 2, 3, 4, 5]; myArray.pop(); console.log(myArray); // [1, 2, 3, 4]
- ‘map()’ 함수를 사용하면 배열 내의 각 요소에 콜백 함수를 적용하여 업데이트된 요소가 포함된 새 배열을 만들 수 있음. 반면 ‘filter()’ 함수를 사용하면 주어진 조건에 따라 배열 요소를 선택적으로 필터링할 수 있음.
각 요소를 평가 후 주어진 조건에 따른 배열 요소를 선택적으로 필터링할 수 있음.
let myArray = [1, 2, 3, 4, 5]; let newAray = myArray.map(function(element)){ return element * 2; }); console.log(newArray); // [2, 4, 6, 8, 10]
- 배열 요소에 대한 보다 복잡한 작업의 경우 for 루프의 기능을 활용함. for 루프를 활용하면 배열의 각 요소를 반복하고 사용자 지정 작업이나 변환을 수행할 수 있음.
let myArray = [1, 2, 3, 4, 5]; for(let i = 0; i < myArray.length; i++){ myArray[i] = myArray[i] * 2; } console.log(myArray); // output: [2, 4, 6, 8, 10]
JS 배열은 참조 유형임. 배열 내 요소를 업데이트하면 변경 사항이 해당 배열에 대한 모든 참조에 전파됨. ‘map()’ 및 ‘filter()’ 함수와 같은 내장 배열 메서드를 활용하고 for 루프를 활용하면 프로세스를 크게 단순화하고 능률화할 수 있음.
배열 요소 업데이트 규칙
- 요소의 인덱스 사용
- 할당 연산자 사용
- 배열 정리 유지
- 내장 배열 메서드 사용:
pop( )
,shift( )
,splice( )
,sort( )
,reverse( )
,concat( )
등. map( )
및filter( )
함수 사용
let과 const를 사용해 배열 결합
배열 결합은 concat()
메서드나 확산 연산자 (...)
를 사용하여 수행
예1: concat() 메서드 사용. concat() 메서드는 여러 배열을 하나의 배열로 병합할 수 있음. 원래 배열은 변경되지 않은 상태로 두 개 이상의 배열을 결합 가능함.
let array1 = [1, 2, 3];
let array2 = [4, 5, 6];
let combinedArray = array1.concat(array2);
console.log(combinedArray) // [1, 2, 3, 4, 5, 6]
예2: 스프레드 연산자 사용 (…) 확산 연산자 ‘(…)’는 해당 요소를 새 배열로 확산하여 배열을 결합할 수 있음.
let array1 = [1, 2, 3];
let array2 = [4, 5, 6];
let combinedArray = [...array1, ...array2];
console.log(combinedArray) // [1, 2, 3, 4, 5, 6]
예3: let과 const 사용. ‘let’ 및 ‘const’ 키워드를 활용하면 병합 프로세스의 결과로 결합된 배열을 저장가능.
let array1 = [1, 2, 3];
let array2 = [4, 5, 6];
let combinedArray = array1.concat(array2);
console.log(combinedArray); // [1, 2, 3, 4, 5, 6]
예4: 스프레드 연산자를 사용하여 배열을 단일 값과 결합.
let array1 = [1, 2, 3];
let combinedArray = [...array1, 4];
console.log(combinedArray); // [1, 2, 3, 4, 5, 6]
예5: 스프레드 연산자를 사용해 배열을 여러 값과 결합.
let array1 = [1, 2, 3];
let combinedArray = [4, 5, ...array1, 4];
console.log(combinedArray); // [4, 5, 1, 2, 3, 6]
예6: 스프레드 연산자를 사용하여 배열과 객체 결합.
let array1 = [1, 2, 3]; let array2 = [4, 5, 6]; let obj = {a: 1, b: 2}; let combinedArray = [...obj, ...array1, ...array2]; console.log(combinedArray); // [1, 2, 1, 2, 3, 4, 5, 6]
let
과 const
를 사용하면 병합된 결과 배열을 저장가능.
concat()
메서드는 원 배열의 모든 요소로 새 배열을 만드는 반면, 스프레드 연산자는 배열 요소를 새 배열로 확장함. 스프레드 연산자를 사용할 때는 요소 순서를 고려하는게 중요하고, concat()
메서드는 원 배열을 변경하지 않지만 스프레드 연산자는 변경한다는 점에 유의.
let 및 const 결합 규칙
concat()
메서드 또는 확산연산자(...)
사용.let
및const
를 사용해 결합된 배열 저장.- 고유한 이름 사용.
- 배열 정리 유지
- 요소 순서를 염두에 둘것.
- 배열 크기에 주의.
- 원본 배열에 유의.
concat()
과 스프레드 연산자의 차이점 이해:concat()
메서드는 원래 배열의 모든 요소를 포함하는 새 배열을 반환, 스프레드 연산자는 배열 요소를 새 배열로 분산시키는 데 유용.`
Length 속성
‘.length’ 속성은 배열 내의 요소 수 또는 문자열 내의 문자 수를 결정하는 목적으로 사용. 배열에 적용하면 .length 속성은 배열에 포함된 총 요소 수를 제공함.
let myArray = [1, 2, 3, 4, 5];
console.log(myArray.length); // 5
JS의 ‘.length’ 속성은 읽기 전용이며 검색은 되지만 수정은 안됨. 또한 1부터 요소나 문자 수를 카운트함.
배열이 본질적으로 동적이며 크기가 수정될 수 있으니만큼, .length 속성은 배열에서 요소를 추가하거나 제거할 때 유용함. .push()
메서드 사용시 배열 끝에 요소를 추가할 수 있고, .pop()
메서드로는 마지막 요소를 제거할 수 있음.
예1:
.length
속성으로 배열 끝에 요소 추가하기
let myArray = [1, 2, 3, 4, 5];
myArray[myArray.length] = 6;
console.log(myArray); //[1, 2, 3, 4, 5, 6]
console.log(myArray.length); // 6
예2:
.length
속성으로 배열 끝에 요소 제거하기
let myArray = [1, 2, 3, 4, 5];
myArray.length = myArray.length -1;
console.log(myArray); //[1, 2, 3, 4]
console.log(myArray.length); // 4
예3:
.length
속성으로 배열 반복하기
let myArray = [1, 2, 3, 4, 5];
for (let i = 0; i < myArray.length; i++ ){
console.log(myArray[i]);
}
.length 속성 사용 규칙
.length
는 메서드가 아닌 속성이라 괄호 호출 불가능..length
는 배열의 요소 수 또는 문자열의 문자 수를 반환.length
속성은 읽기 전용입니다. 즉, 속성 값을 검색하는 데 사용할 수 있지만 설정하는 데는 사용할 수 없음..length
는 1부터 요소나 문자 수를 세기 시작하고, 배열이나 문자열의 첫 번째 요소나 문자부터 세기 시작..length
속성을 사용하여 배열에서 요소를 추가하거나 제거.length
는 배열 및 문자열 객체의 속성이므로 다른 유형의 객체와 함께 사용할 수 없음..length
속성을 사용하면 배열을 반복하여 각 요소에 액세스가능.length
는 객체의 속성 수를 계산하지 않으며 배열의 요소 수 또는 문자열의 문자 수만 계산함.
.push() 메서드
‘.push()’ 메서드를 사용하여 배열 끝에 하나 이상의 요소를 추가할 수 있음. 원래 배열이 수정되고 배열 길이가 결과로 반환됨. 요소를 기존 배열에 편리하고 효율적으로 추가.
let myArray = [1, 2, 3];
myArray.push(4);
console.log(myArray); // [1, 2, 3, 4]
단일 요소 외에도 여러 요소를 추가할 수도 있음.
let myArray = [1, 2, 3];
myArray.push(4, 5, 6);
console.log(myArray); // [1, 2, 3, 4, 5, 6]
새 배열이 생성되는 것이 아니라 원 배열이 수정됨. 또한 새 length가 반환되므로 요소 추가 후 업데이트 된 길이에 엑세스 할 수 있음.
.pop() 메서드
‘.pop()’ 메서드를 사용하여 배열의 마지막 요소를 제거할 수 있음. 끝에서 요소를 제거하고 원래 배열을 수정하며 제거된 요소를 반환함. 배열의 길이도 업데이트 됨.
let myArray = [1, 2, 3];
let lastElement = myArray.pop();
console.log(myArray); // [1, 2]
console.log(lastElement); / 3
배열이 비어 있고 ‘.pop( )’ 메서드가 호출되면 오류를 발생시키지 않고 undefined를 반환한다는 점은 주목할 가치가 있음, 또한 ‘.pop( )’ 메서드는 새 배열을 만드는 대신 마지막 요소를 제거하여 원래 배열을 수정함.
.pop() 메서드 규칙
.pop( )
메서드는 배열에서 마지막 요소를 제거하고 이를 반환..pop( )
메서드는 원래 배열을 수정하지만 새 배열을 생성하지는 않음..pop( )
메서드는 제거된 요소를 반환하므로 변수에 할당하거나 표현식에 사용할 수 있음..pop( )
메서드는 비어 있지 않은 배열에만 사용할 수 있습니다. 배열이 비어 있으면 오류없는undefine
을 반환함..pop( )
메서드는 배열에 사용하도록 특별히 설계되었습니다. 배열이 아닌 객체에 사용하면undefine
‘을 반환..pop( )
메서드는 또한 배열의length
속성을 변경하고 요소를 제거한 후 1씩 줄임..pop( )
메서드는 다른 배열 메서드와 연결되어 단일 명령문으로 배열에 대해 여러 작업을 수행할 수 있음..pop( )
메서드는 어떤 인수도 허용하지 않으며 값에 관계없이 배열에서 마지막 요소를 제거.
배열과 함수
배열과 함수는 서로 상호작용하는데 일반적으로 배열을 함수에 인수로 전달하여 배열 내 요소에 작동하는 함수를 만드는 것임.
function doubleValues(arr){
for(let i = 0; i < arr.length; i++){
arr[i] = arr[i] * 2;
}
return arr;
}
console.log(doubleValues([1, 2, 3])); // [2, 4, 6]
다른 응용법은 함수 내에서 배열 메서드를 활용하는 것. 예를 들어 .forEach()
메서드의 기능을 활용해 배열 요소를 반복하고 각 요소에 대해 원하는 작업을 실행할 수 있음.
이 접근 방식은 명시적인 루프 구성 없이 배열의 모든 요소에 함수를 편리하게 적용할 수 있음.
function printValues(arr){
arr.forEach(function(element){
console.log(element);
});
}
printValues
({1, 2, 3}); // logs "1", "2", "3"
배열 .map()
메서드롤 활용해 원래 배열 요소 기반으로 새 배열을 생성할 수 있음.
function doubleValues(arr){
return arr.map(function(element)){
return element * 2;
});
}
console.log(doubleValues([1, 2, 3])); // [2, 4, 6]
함수에서 배열을 반환하고 나중에 사용하려고 변수에 할당할 수 있음.
function getNumber(){
return [1, 2, 3];
}
let numbers = getNumbers();
console.log(numbers); // [1, 2, 3]
배열과 함수는 배열을 함수 인수로 전달하고 함수 내에서 배열 메서드를 활용, 기존 배열 기반으로 새 배열을 만들거나 함수에서 배열을 반환해 이를 변수에 할당하는 등의 방법으로 활용이 가능함.
배열과 함수 규칙
- 배열은 함수에 인수로 전달될 수 있으므로 함수가 배열 요소에 대해 작업을 수행할 수 있음.
.forEach( )
,.map( )
,.filter( )
,.reduce( )
등과 같은 배열 메서드를 함수 내에서 사용하여 배열 요소에 대한 작업을 수행할 수 있음.- 함수는 배열을 반환할 수 있으므로 호출자가 반환된 값을 변수에 할당하고 배열로 작업할 수 있음.
- 배열 요소는 변경 가능합니다. 즉, 해당 값이 생성된 후에도 변경될 수 있음.
- 배열 요소는 숫자, 문자열, 객체 및 기타 배열을 포함한 모든 유형
- 배열은 객체이므로 다른 객체처럼 액세스할 수 있는 속성과 메서드를 갖음.
- JS의 배열 메소드 대부분은 원래 배열을 변경하지 않고, 대신 원하는 변경 사항이 포함된 새 배열을 반환.
- JS 배열 인덱스는 0부터 시작.
더 많은 배열 기능
.forEach()
메소드는 배열의 각 요소를 반복하고 각 요소에 대해 특정 작업을 수행할 수 있는 편리한 도구임. for 루프를 작성할 필요 없이 배열을 반복하고 각 요소에 코드를 실행하는 편리함을 제공.let myArray = [1, 2, 3]; myArray.forEach(function(element)){ console.log(element); });
.map()
메서드는 제공된 함수를 원본 배열의 각 요소에 적용한 결과를 바탕으로 새 배열을 생성하는 함수. 배열의 각 요소에 대해 실행되는 콜백함수를 인수로 사용.let myArray = [1, 2, 3]; let newArray = myArray.map(function(element)){ return element * 2; }); console.log(newArray); // [2, 4, 6]
.filter()
메서드는 제공된 함수에 의해 구현된 지정 조건을 통과한 요소로 새 배열을 생성함.let myArray = [1, 2, 3, 4, 5]; let newArray = myArray.filter(function(element)){ return element % 2 === 0; }); console.log(newArray); // [2, 4]
.reduce()
메서드는 배열 요소를 왼쪽에서 오른쪽으로 적용하고 단일 값으로 줄이기 위해 콜백함수를 배열 요소에 적용함.let myArray = [1, 2, 3, 4, 5]; let total = myArray.reduce(function(accumulator, currentValue){ return accumulator + currentValue; }, 0); console.log(total); // 15
.sort()
메서드는 배열의 요소를 제자리에 정렬하고 정렬된 배열을 반환함. 새 배열을 만들지 않고 원본 배열을 직접 수정함. 비교를 위해 UTF-16 코드 단위값을 사용함. 특정 기준에 따른 정렬순서를 정의하기 위해 사용자 정의 비교함수를 인수로 넣을 수 있음. 비교 함수는 결과에 따라 음수, 0, 양수 값을 반환해야 함.- a가 b보다 작으면 음수 값
- a가 b보다 크면 양수 값
- a와 b가 동일한 것으로 간주되어야하면 0
let myArray = [3, 1, 2];
myArray.sort();
console.log(myArray); // [1, 2, 3]
.slice()
메서드는 기존 배열의 일부 복사본인 새 배열을 반환함. 원본 배열을 수정하지 않고도 배열의 특정 섹션을 추출할 수 있음. 끝 인덱스는 미포함.
let myArray = [1, 2, 3, 4, 5];
let netArray = myArray.slice(1, 3);
console.log(newArray); // [2, 3]
.concat()
메서드는 호출된 배열을 인수로 전달된 다른 배열 또는 값과 결합하는 새 배열을 반환함. 원래 배열은 수정되지 않으며, 이 메서드로 여러 배열의 모든 요소를 포함하는 새 배열을 만들거나 기존 배열에 개별 값을 추가할 수 있음.
let myArray = [1, 2, 3];
let newArray = myArray.concat([4, 5], [6, 7]);
console.log(newArray); // [1, 2, 3, 4, 5, 6, 7]
.indexOf()
메서드는 배열의 특정 요소의 첫 번째 인덱스를 반환하거나 해당 요소를 찾을 수 없는 경우 -1을 반환.
let myArray = [1, 2, 3, 4, 5];
let index = myArray.indexOf(3);
console.log(index); //2
- .slice(start, end)
- .sort(compareFunction)
- .concat(array2, arra3, …)
- 올바른 인수를 사용해야함.
중첩 배열(nestedArray)
배열의 배열 요소임. 배열 내 계층 구조를 만들 수 있음. 배열 구조를 탐색하려면 추가 인덱스를 사용해 각 중첩 수준에 엑세스함.
‘nestedArray’ 는 요소로 3개의 배열로 구성된 중첩 배열로서 1번째 배열의 2번째 요소에 엑세스 하려면
nestedArray[0][1]
인덱스를 사용함.
let nestedArray = [[1, 2], [3, 4], [5, 6]];
console.log(nestedArray[0],[1]); //2
중첩 배열은 일반 배열과 마찬가지로 .push()
,.concat()
,.splice()
등의 다양한 배열 메서드를 사용할 수 있음.
중첩 배열은 복잡한 데이터 구조를 표현하고 구성하는데 유용함.
let nestedArray = [[1, 2], [3, 4]];
nestedArray[0].push(5);
console.log(nestedArray); // {[1, 2, 5], [3, 4]}
중첩 배열 처리 시 중첩 수준 내 특정 요소에 엑세스하려면 적절한 인덱스를 고려해야하며 다차원 배열 개념과 인덱스가 외부 배열에서 내부 배열로 계단식 배열인 것을 이해해야 함.
예1: 행렬을 나타내는 2D 배열
let matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
console.log(matrix[0][1]); //2
예2: 학생 목록 및 정보
let students = [["John", 25, "male", ["math" , "history"]], ["Emily", 23, "female", ["chemistry", "physics"]], ["Micheal", 27, "male", ["biology", "computer science"]]];
console.log(student[0],[0]+ " is " + student[0][2] + " and is taking " + student[0][3][1] + " class."); // john is male and is taking history class.
예3: 레스토랑 메뉴 및 하위 항목
let menu = [["Appetizers", ["Wings", "Nachos", "Morrarella Sticks"]],["Entrees", ["Steak", "Fish and Chips", "Spaghetti"]], ["Desserts",["Cheesecake", "Tiramisu", "Creme Brulee"]]];
console.log("Our menu includes: " + menu[0][1][1] + menu[1][1][1] + " , and" + menu[2],[1],[1] + ".");
// Our menu includes: Nachos, Fish, and Chips, and Tiramisu.
예4: 장바구니
let cart = [ ["Apple", 2, 0.5], ["Banana", 5, 0.25],["Orange", 3, 0.75]];
console.log(cart[1],[0] + " " + cart[1][1] + " " + cart[1][2]*cart[1][1]); // banana 5 1.25
중첩배열 규칙
- 중첩 배열의 요소에 엑세스하려면 각 중첩 수준마다 하나씩 여러 인덱스가 필요함. ‘nestedArray[0][1]’ 등
- 중첩 배열 요소를 수정하려면 중첩 수준마다 하나씩 여러 인덱스가 필요함. 두 번째 요소를 변경하려면 할당 연산자 ‘nestedArray[0][1] = newValue’를 사용함.
- 배열의 길이 속성은 배열의 요소 수를 반환함.
.push( )
,.concat( )
,.splice( )
,.map( )
등의 Array 메서드는 일반 배열과 같이 사용가능.- 중첩 배열 반복시 중첩 수준과 요소에 엑세스 하려면 올바른 인덱스를 사용해야함.
.sort()
또는 .splice()
같은 원래 배열을 수정하는 메서드 사용시 주의할 것. 이런 메서드는 원래 배열을 변경함.- 크고 복잡한 중첩 배열 작업시 함수를 사용해 동일 논리의 중복을 피하고 코드 가독성을 늘림.
- 중첩 배열을 조작하는 것은 일반 배열보다 더 복잡하므로 작동방식을 이해해야 함.