🔑배열과 함수 모두 ✅객체로 왜 그러한지, 어떻게 쓸 수 있는지까지 알아보장!
WHAT IS❓
우리가 배운 데이터 타입에 따르면 자바스크립트는 크게 기본형 타입(primitive type)과 참조형 타입(Reference Type) 으로 나눠지고
이 참조형 데이터 타입에는🗝 오늘의 키워드 🔐객체가 있고 이 객체의 하위 부류로 🔑배열과 🗝️함수가 포함되어 있다
이제 우리가 알아야할건 🔑배열과 🗝️함수를 나눠서
1> 왜 배열과 함수가 객체인지?
2> 어떻게 하면 객체인 배열과 함수를 더 잘 다룰 수 있는지!
두 가지를 중점으로 살펴보자~ 레고!
WHY❔❕
🔐객체라는 자료구조는
키
를 사용해식별할 수 있는 값(키의 값)
을 담은 컬렉션으로 이를 이용해 데이터를 저장할 수 있고 객체만으로도 다양한 작업들이 충분히 가능하다.
- A. 개발을 하다 보면 첫 번째 요소, 두 번째 요소, 세 번째 요소 등과 같이 순서가 있는 컬렉션이 필요할 때가 있다.
(EX> 사용자나 물건, HTML 요소 목록같이 일목요연하게 순서를 만들어 정렬하는 작업 등)
<문제점>
- 이렇게 순서가 있는 컬렉션을 다뤄야 할 땐 🔐객체를 사용하면 순서와 관련된 메서드가 없어 불편하다.
- 객체는 태생이 순서를 고려하지 않고 만들어진 자료구조이기 때문에 객체를 이용하면 새로운 프로퍼티를 기존 프로퍼티 사이에 끼워 넣는 것도 불가능하다.
<해결책>
- 이처럼
순서
가 있는 컬렉션을 저장해야하는 상황이 생길 때 쓰는 자료구조가 바로 🔑배열이다.
- 1> 🔑배열은 특별한 종류의 객체입니다.
- 1.1>배열 arr의 요소를 접근할때 arr[0]처럼 대괄호를 사용하는 방식도 사실은 객체 문법에서 왔다.(대박이죠..!)
- 1.2> 다만 🔑배열은 키가 숫자라는 점이 특징이다.
- 2> 숫자형 키(배열에선 인덱스)를 사용함으로써 배열은 객체 기본 기능 이외에도
순서
가 있는 컬렉션을 제어할 수 있는 특별한 메서드를 제공를 가진다.
(EX> 메서드 뿐만 아니라 length 프로퍼티(배열의 길이를 알려주는) 역시 제공)
<script> let fruits = ["사과", "오렌지", "배"] // 1. 배열을 값으로 가진 변수 fruits를 새로운 변수에 재할당하여 복사 let arr = fruits; // 이때 값이 아닌 참조를 복사(따라서 현재 두 변수가 같은 객체를 참조한다) console.log( arr === fruits ); // true // 1. 배열을 값으로 가진 변수 fruits를 수정 arr.push("딸기"); // 이때 역시 참조를 이용해 배열을 수정 console.log(fruits); // ["사과", "오렌지", "배", "딸기"] - 요소가 네 개로 됨 </script>
<script> let fruits = []; // 빈 배열을 하나 생성 fruits[10] = 5; // 배열의 길이보다 훨씬 큰 숫자를 사용해 프로퍼티를 할당 fruits.age = 25; // 임의의 이름으로 프로퍼티를 만들어도 문제 X console.log(fruits) // [empty * 9, 5] </script>
🔅주의🔅)
다만 이렇게 코드를 작성하면 자바스크립트 엔진이 배열을 일반 객체처럼 다루게 되어 배열 특유의 이점이 사라지니 배열은 배열답게 사용하자.
<script> let arr = ["사과", "오렌지", "배"]; for (let key in arr) { console.log( key ); // 0, 1, 2 => 키를 조회, 즉 인덱스 값이 나온다 console.log( arr[key] ); // 사과, 오렌지, 배 => 배열[키], 배열의 요소가 나온다. } </script>
- BUT>
for..in 반복문
은 배열이 아닌 객체와 함께 사용할 때 최적화되어 있어서 배열에 사용하면 객체에 사용하는 것 대비 10~100배 정도 느리다는 것!
for..in 반복문
을 쓰지말고 배열의 다른 순회 문법인 for..of 반복문
을 사용하자. <script> let arr = ["사과", "오렌지", "배"]; // 배열 요소를 대상으로 반복 작업을 수행합니다. for (let key of arr) { console.log( key ); // "사과", "오렌지", "배" } </script>
- 이러한 이유들로 인해 🔑배열의 본질은 바로 객체(특수한 형태의)로
순서
가 있는 자료를 저장하고 관리하는 용도에 최적화된 자료구조입니다.- 배열 내장 메서드(push, pop, slice 등등)들 역시 이러한 용도에 맞게 만들어진 것으로 배열을 사용할 땐 목적에 맞게 사용하는 것을 권장합니다.
- 임의의 키(숫자형이 아닌)를 사용해야 한다면 배열보단 일반 객체 {}가 적합한 자료구조일 것이다.
- A. 개발을 하다 보면 첫 번째 요소, 두 번째 요소, 세 번째 요소 등과 같이 순서가 있는 컬렉션이 필요할 때가 있다.
(EX> 사용자나 물건, HTML 요소 목록같이 일목요연하게 순서를 만들어 정렬하는 작업 등)
<문제점>
- 이렇게 순서가 있는 컬렉션을 다뤄야 할 땐 🔐객체를 사용하면 순서와 관련된 메서드가 없어 불편하다.
- 객체는 태생이 순서를 고려하지 않고 만들어진 자료구조이기 때문에 객체를 이용하면 새로운 프로퍼티를 기존 프로퍼티 사이에 끼워 넣는 것도 불가능하다.
<해결책>
- 이처럼
순서
가 있는 컬렉션을 저장해야하는 상황이 생길 때 쓰는 자료구조가 바로 🔑배열이다.
일급객체
란?
- 자바스크립트에서 🗝️함수는
일급 객체
인데 *다음의 조건을 만족하면일급 객체
입니다1. 변수(variable)나 자료구조(객체, 배열)에 저장할 수 있다. 2. 함수의 인자(parameter)로 전달할 수 있다. 3. 함수의 반환값(return value)으로 전달할 수 있다.
- 이처럼 함수가
일급 객체
라는 건 함수를 객체와 동일하게 사용할 수 있다는 것을 의미합니다. 객체는 값이므로 함수 역시 값과 동일하게 취급하는 거죠.
<script> //변수 variable에 함수 리터럴을 할당한 식 const cal = function add(x, y){ return x + y; } </script>
위 코드처럼 함수 리터럴을 변수에 할당하고 있는데요. 여기서 리터럴이란 값을 생성하기 위한 표기법(사람이 이해할 수 있는 문자 또는 약속된 기호를 사용)입니다. 따라서 함수 리터럴도 평가되어 값을 생성하고 있습니다.
<script> // 변수에 함수 할당 const name = function() { return 'minjae'; }; console.log(name()); // minjae // 프로퍼티에 함수 할당 const obj = {}; obj.langauge = function() { return 'javaScript'; }; console.log(obj.langauge()); // javaScript </script>
- 위 코드의 langauge처럼 객체의 프로퍼티에도 함수를 할당할 수 있고 배열의 원소로도 할당이 가능하다.
<script> // 함수 표현식으로 passer() 함수를 생성 const passer = function(func) { func(); // 인자로 함수를 넘겨받고 넘겨받은 func() 함수를 호출한다. } //passer() 함수 호출 시 passer(function(){ // passer 함수의 인수로 함수 자체를 전달한다. console.log('나는 함수의 인자로 전달되었습니당!'); });// '나는 함수의 인자로 전달되었습니당!' </script>
- passer() 함수를 호출 시 함수 자체를 func 인자로 넘겨서 passer() 함수 내부에서 func 매개변수로 인자에 넘겨진 함수를 호출합니다.
<script> // 함수를 다른 함수의 리턴값으로 활용한 코드 // 함수를 리턴하는 foo() 함수 정의 const foo = function() { return function() { // 함수를 리턴 console.log('이 함수는 함수를 반환한다.'); }; }; // foo() 함수가 호출되면, 리턴값으로 전달되는 익명함수가 bar 변수에 저장된다. const bar = foo(); // 익명함수를 호출하기 위해서 ()인 함수호출 연산자를 이용해 bar()로 익명함수를 호출, 실행한다. bar(); // ('이 함수는 함수를 반환한다.') </script>
<script> function minus(x,y) { return x - y; } // 함수 역시 객체처럼 프로퍼티를 가질 수 있다. // 함수 객체에 anwser 프로퍼티를 추가하고 값으로 함수를 호출하여 넘겨준다. minus.result = minus(4,1); console.log(minus.result); // 1 </script>
- 함수 자체가 일반 객체처럼 프로퍼티를 생성하고 할당이 가능합니다.
- minus()함수는 result 프로퍼티를 생성하고 minus()함수 호출 결과 값을 생성한 함수의 result 프로퍼티에 저장할 수 있습니다.
- 일반 객체의 접근방식처럼 minus.result를 이용해 접근도 가능하죠.
- 자바스크립트에서 함수는 특정기능의 코드를 수행할 뿐만 아니라, 일반 객체처럼 자신의 프로퍼티를 가질 수 있는 특별한 객체(일급)입니다.
- 일급 객체로서 함수가 가지는 가장 큰 특징은 일반 객체와 같이 함수의 매개변수에 전달할 수 있으며 함수의 반환값으로도 사용할 수 있다는 점 입니다.
- 일반 객체와의 차이점은 일반 객체는 호출할 수 없지만 함수 객체는 호출할 수 있고 일반 객체엔 없는 함수 고유의 프로퍼티를 소유합니다
- 함수와 배열 모두 객체입니다! 객체에 대해서 공부하시다보면 더 이해가 잘 갈거같아요! 배열이 가진 특수한 메서드 함수 고유의 프로퍼티와 같이 객체와 다른 배열과 함수만의 특징 역시 공부하시면 더 좋습니당..!
- 책 - 딥다이브
- 자바스크립트 튜토리얼 배열 편 - https://ko.javascript.info/array