JavaScript Drill #4

sway3·2023년 4월 15일
0

JS Drill

목록 보기
4/4
post-thumbnail

javascript.info 객체:기본 4.5 (new 연산자와 생성자 함수) ~ 4.8

1. 생성자 함수

생성자 함수의 기본

객체 리터럴 {...} 을 사용하면 객체를 쉽게 생성할 수 있었다.

다음과 같이 생성자 함수를 이용하여 객체를 생성하면 유사한 객체를 여러 개 만들어야 할 때 유용하게 사용할 수 있다.

우선 생성자 함수를 사용하여 객체를 생성할 때 지켜야할 몇 가지 관례가 있다.

  1. 함수의 이름의 첫 글자는 대문자로 시작해야한다.

  2. this 키워드를 사용하여 프로퍼티를 선언해야한다.

  3. 반드시 new 연산자를 붙여서 실행해야한다.

function User(name) {
  this.name = name;
  this.isAdmin = false;
}

let user = new User("보라");

alert(user.name); // 보라
alert(user.isAdmin); // false

위의 코드에서 new User("보라") 가 실행되면 다음과 같은 단계를 따른다.

  1. this 라는 이름의 빈 객체 생성

  2. this 객체에 name 과 isAdmin 프로퍼티와 그에 해당하는 값을 할당

  3. this 를 반환 후 user 에 할당

생성자 함수와 return

생성자 함수 내부에서 return 은 생략된다. 프로퍼티들을 this에 반환하고 this 는 자동으로 반환되기 때문에 return 문을 굳이 써주지 않아도 된다.

하지만 다음의 코드처럼 return 문을 사용하고 다른 객체를 반환한다고 코드를 작성하면 this 가 아닌 다른 객체가 반환된다.

function BigUser() {

  this.name = "원숭이";

  return { name: "고릴라" };  // <-- this가 아닌 새로운 객체를 반환함
}

alert( new BigUser().name );  // 고릴라

생성자 내 메소드

다음과 같이 생성자 내부에 메소드를 선언할 수 있다.

function User(name) {
  this.name = name;

  this.sayHi = function() {
    alert( "제 이름은 " + this.name + "입니다." );
  };
}

let bora = new User("이보라");

bora.sayHi(); // 제 이름은 이보라입니다.

/*
bora = {
   name: "이보라",
   sayHi: function() { ... }
}
*/

2. 심볼형 (Symbol)

심볼은 유일한 식별자 (unique identifier) 을 만들고 싶을 때 사용된다.

let id = Symbol('id');

위와 같이 Symbol() 을 이용하여 심볼을 만들 수 있으며, 인자로 string 값을 전달하여 해당 심볼에 대한 description 을 원하는대로 작성할 수 있다. 이 description 은 .description 로 쉽게 출력할 수 있다.

심볼은 그 어떤 문자형으로도 변형될 수 없다고 한다. 꼭 심볼을 문자열로 변환하여 출력하고 싶다면 .toString() 메소드를 사용하도록 하자.

숨김 프로퍼티

Symbol 을 사용하면 객체에 숨겨진 프로퍼티를 부여할 수 있다.

let person = {
	name = 'Bob'
};

let id = Symbol('id');
person[id] = 1;

alert( person[id] );

프로퍼티 id 는 심볼형으로서 person 이라는 객체의 프로퍼티 중 하나이며, 이는 외부 코드에서 접근이 불가하고 수정할 수 없다고 한다.

또한 숨김 프로퍼티는 for...in 의 iteration 에서 배제된다고 한다.

전역 심볼

심볼은 이름이 같아도 별개로 취급하지만, 같은 심볼이 같은 개체를 가리켜야하는 경우에는 전역 심볼을 사용하면 된다.

Symbol.for(key) 를 사용하면 전역 심볼 레지스트리에서 심볼을 읽고, 만약 해당 심볼이 존재하지 않다면 새로운 심볼을 생성할 수 있다.

let id = Symbol.for('id');
let id2 = Symbol.for('id');

alert(id === id2); //true

Symbol.keyFor(sym) 을 사용하면 심볼을 이용하여 심볼의 이름을 얻을 수 있다.

let id = Symbol.for('user');
let name = Symbol.keyFor(id);

alert(name); //user

3. 객체의 형변환

객체를 원시형으로 변환하기

let num = 1;
alert(num);

위와 같은 코드처럼, num은 숫자형이지만 alert로 출력할 때는 문자형으로 자동으로 형변환되어 출력된다.

원시형 데이터 타입들끼리는 이처럼 형변환이 자유롭게 가능했다.

하지만 객체끼리 수학 연산을 수행하거나, 문자형 데이터 타입에만 사용할 수 있는 메소드를 사용할 수 있다고 한다.

obj[Symbol.toPrimitive] = function(hint) {
  // 반드시 원시값을 반환해야 합니다.
  // hint는 "string", "number", "default" 중 하나가 될 수 있습니다.
};

객체 내부에 다음과 같은 메소드를 추가하면 된다.

Symbol.toPrimitive 는 자바스크립트의 내장심볼로, 객체를 형변환 할 때 목표로 하는 자료형 (hint) 을 명명하는데 사용한다고 한다.

hint 는 'string', 'number', 'default' 중 하나의 값을 가질 수 있다. 객체가 어떤 자료형으로 변환해야할지 확신이 없을 때 default 값이 된다고 한다. boolean 은 항상 true를 반환하기 때문에 boolean 은 존재하지 않는다.

객체를 형변환할 때는 다음과 같은 단계를 따른다.

  1. 객체 내부에 Symbol.toPrimitive 메소드가 구현되어있는지 확인한다.

  2. 구현되어있다면, 'hint' 를 전달하고 해당 메소드를 호출한다.

  3. Symbol.toPrimitive 가 구현되어있지 않거나 hint 에 따른 반환값을 정하지 못한 경우에는 hint 값에 따라 자동으로 toString 이나 valueOf 를 이용하여 형변환을 시도한다.

예시를 들어 쉽게 객체가 형변환 되는 과정을 설명해보자면,

let user = {
	id: 1,
    name: 'Bob'
    
    [Symbol.toPrimitive](hint) {
    	return hint == "string" ? this.name : this.id;
    }
};

alert(user);

위의 코드에서 alert 함수가 user를 인자로 받았다.

alert 는 인자를 문자형으로 자동으로 형변환하는데, user 는 객체이므로 우선 객체 내부에 Symbol.toPrimitive 메소드가 구현되어있는지 확인할 것이다.

위의 코드에는 구현이 되어있으므로, hint 값을 전달 받아 string 인지 아닌지 확인한다. 목표로 하는 자료형은 string 이므로 this.name 을 return 해줄 것이다.

위의 과정을 거쳐 alert(user) 은 'Bob' 을 return 한다!

toString() 과 valueOf() 는 오래된 방법이라고 하니 따로 기록해두진 않겠다.

profile
병아리 개발자

0개의 댓글