본문 바로가기

자바스크립트

자바스크립트) 함수 내 d내장함수와 프로토타입

아무런 생각없이 사용하던 Array.sort(), length 등등의 함수들.



최근에 궁금증이 하나 생겨났다.

자바스크립트를 처음 공부할 때 분명 봤었던 것이지만, 시간이 지나 잊어버리고 다시 공부하며 다시 한 번 더 정리하려 한다.

 

아무런 생각없이 사용하던 Array.sort(), length등등의 함수들은 어떻게 사용되는 것일까.

예를들어 다음과 같은 배열이 있다고 해보자.

  const arr = [5,4,3,2,1]

이 함수를 정렬하기 위해선 여러 방법이 있다.

시간복잡도를 생각해 선택 정렬, 버블정렬, 퀵 정렬 등을 선택할 수 있겠지만 보통은 array.sort()로 정렬을 시행한다.

arr.sort();
console.log(arr); //[1, 2, 3, 4, 5]

참으로 간단하지 않은가.

단지 array.sort()만으로 배열 요소들을 정렬시킬 수 있다!

그럼 이런 의문이 생길 것이다.

sort()는 어디서 나온 것일까.

이를 알기 위해선 우선 프로토타입을 봐야한다.


자바스크립트의 프로토타입

Java, C++과 같은 클래스 기반 객체지향 프로그래밍 언어와 달리 자바스크립트는 프로토타입 기반 객체지향 프로그래밍 언어이다.

자바스크립트에서 객체를 생성하는 방법은 대체로 다음과 같다.

  const obj = {
    name: "kim",
    age: 20,
  };

  console.log(obj); //{name: 'kim', age: 20}

만일 100개의 객체를 생성해야 한다면?

단순히 위 코드를 100번이나 복붙해야한다. 또는 반복문을 사용하던가.

하지만 이를 간소화 해서 매우 간단히 객체를 생성할 수 있다.

      function Person(name, age) {
        (this.name = name), (this.age = age);
      }

      const person = new Person("kim", 20);
      console.log(person); //Person {name: 'kim', age: 20}

클래스와 생성자 함수에 대해선 다음에 다루기로 하겠다.

단순히 new FunctionName()을 통해 객체를 생성한다.

얼마나 간단한가.

Person은 부모고 person은 자식으로 생각해보자.

부모의 것을 그대로 자식이 물려받아 새 객체를 생성한다.

만일 새로운 것을 추가하려면 다음과 같이 추가할 수 있다.

function Person(name, age, height) {
        (this.name = name), (this.age = age);
        this.height = height;
      }

      const person = new Person("kim", 20, 170);
      console.log(person); //Person {name: 'kim', age: 20, height: 170}
      
  //or
  
  function Person(name, age) {
        (this.name = name), (this.age = age);
      }

      Person.prototype.height = 170;

      const person = new Person("kim", 20);
      console.log(person); //Person {name: 'kim', age: 20}
엥? 밑 결과에선 height가 나오질 않는데요?

그 이유는 바로 height는 인스턴스 속성이 아닌 프로토타입의 속성으로 정의되었기 때문이다.

 

프로토타입이요?

앞서 말했던 부모와 자식을 기억하는가

쉽게 설명하기 위해 부모와 변수라는 말을 사용했지만 실제로는 "원형"이란 의미에 가깝다.

person이라는 원형. 즉 name과 age를 가지는 오브젝트라는 말이다.

 

자 다시 위 코드로 돌아가보자. Person이라는 생성자에 height속성을 추가하고 height는 인스턴스가 아닌 프로토타입으로 정의 되었다.

그런데 콘솔을 확인해보면 여전히 name,age만 나온다.

height는 프로토타입으로 정의 되어있고 콘솔창에는 나오지 않는다.

여기서 유추할 수 있는 것은 콘솔은 단순히 프로토타입 체인을 확인하지 않고 직접적인 인스턴스만 출력한다는 것을 알 수 있다.

  console.log(person.height); // 170

height를 찍어보면 잘 나온다.

 

그런데 여전히 의문점이 생긴다.

인스턴스엔 height가 있고 프로토에는 height가 있지만 콘솔은 인스턴스만 출력한다고 하지 않았나요?

맞는 말이다.

그 답은 자바스크립트 실행 방식에 있다.

오브젝트를 출력할 때 obj.name으로 출력을 하곤한다. 그럼 우선 인스턴스에 접근을 해 name을 확인하고 인스턴스에 name이 없다면 그 부모로 넘어가게 된다.

따라서 단순한 콘솔에는 height가 없지만 person.height에는 값이 온전히 찍히게 되는 것이다.

 

그래서 Array.sort()는 무엇이죠?

 

Array에도 단순히 []로 배열을 생성하는 방식이 있지만 다음과 같은 방식이 있다.

  const arr = new Array(1, 2, 3);
  console.log(arr);//(3) [1, 2, 3]

new... 어디서 많이 보지 않았는가.

맞다. 생성자 함수이다.

Array라는 것을 콘솔창에 찍어보면 native code라는 것이 나오지만 프로토타입을 찍어보면 indexOf() 등등의 내장함수를 볼 수있다.

      console.log(Array.prototype);

 

정리해보면 new Array()등의 생성자 함수에는 프로토타입이 존재하고 그 프로토타입은 여러가지가 존재하지만 

new Array에는 sort(), indexOf()등의 내장함수가 존재한다.

따라서 그 내장함수를 호출하므로써 sort()함수를 따로 선언하지 않아도 사용할 수 있는 것이다.