[JS] Object (심화)

mokyoungg·2020년 5월 6일
1
post-custom-banner

출처는 코드카데미입니다.
https://www.codecademy.com/learn/introduction-to-javascript

자바스크립트의 객체는 데이터와 함수를 저장하는 컨테이너이다.

1. The this keyword

객체는 관련 데이터 및 함수의 모음이다.
이러한 함수를 객체의 메소드에 저장한다.

const giants = {
  hometown : 'Busan',
  makeSound() {
    console.log('ma!');
  }
};

위의 예시에서, giants 객체는 makeSound() 메서드를 가지고 있다.
다음과 같은 방법으로 .makeSound() 메서드를 호출할 수 있다.

giants.makeSound(); // Prints ma!

만약 giants의 hometown 값을 프린트하는 .hometown()이라는 메서드를
giants 객체에 새로 추가하고 싶다면 어떻게 해야할까?

const giants = {
  hometown : 'Busan',
  makeSound() {
    console.log('ma!');
  },
  hometown() {
    console.log(hometown);
};

giants.hometown();
// Output will be "ReferenceError: hometown is not defined"

정의되지 않았다. 위에 프로퍼티가 있는데 정의되지 않았다.
이는 .hometown() 메서드의 범위 안에서 자이언츠 객체의 다른 속성에 자동으로 접근할 수 없기 때문이다.
이런 상황에서! this 키워드가 해답이 된다. this! this! this! 이것!

const giants = {
  hometown : 'Busan',
  makeSound() {
    console.log('ma!');
  },
  hometown() {
    console.log(this.hometown);
};

giants.hometown(); // Output: 'Busan'

this 키워드는 호출된 객체의 프로퍼티에 대한 엑세스를 제공한다.(호출된 객체를 참조한다.)

2. 화살표 함수와 this

const giants = {
  hometown : 'Busan',
  makeSound() {
    console.log('ma!');
  },
  hometown: () => {
    console.log(this.hometown);
};

giants.hometown(); // Prints undefined

.hometown() 은 화살표 함수를 사용하여 정의하였다.
화살표 함수는 이 값을 호출 객체가 아닌 함 수 자체에 본질적으로 바인딩하거나 묶는다.

위의 코드에서 this의 값은 글로벌 범위에 존재하는 오브젝트다. 즉, hometown 프로퍼티가 없는
글로벌 범위에 존재하는 오브젝트이며 따라서 undefined가 반환된다. ???????????????????????????????????

무슨 말인지는 모르겠지만, 아무튼
this를 사용할 때 화살표 함수를 사용하지 말라는 것이다.

3. Privacy

프로퍼티 접근 및 업데이트는 객체 작업에 있어 기본 사항이다.
그러나, 단순히 객체의 프로퍼티에 접근하고 업데이트하는 것을 원하지 않는 경우도 있다.
privacy를 객체에서 논할 때는 특정 프로퍼티만 변이가 가능하거나 값이 변할 수 있어야 한다는
생각으로 정의한다..?

특정 언어에는 객체에 대한 개인 정보 보호 기능이 내장되어 있지만, 자바스크립트에는 이 기능이 없다.
오히려, 자바스크립트 개발자들은 프로퍼티와 상호작용하는 방법을 알리는 명명 규칙을 따른다. ?
관습으로, 프로퍼티가 변경되지 않도록 프로퍼티의 이름 앞에 밑줄을 치는 것이다.(_)

const bankAccount = {
  _amount: 1000
}

위의 예에서, _amount 는 직접 조작할 의도가 없다.
그러나 _amount 는 재할당이 가능하다.
(그냥 하지말라는 표시인듯, 여기서 담배피지 마세요 같은거)

5. Getters

getters 는 객체의 내부 프로퍼티를 가져와서 반환하는 방법이다.
그러나 단지 프로퍼티를 가져오는 것 이상을 할 수 있다.

const person = {
  _firstName: 'John',
  _lastName: 'Doe',
  get fullName() {
    if (this._firstName && this._lastName){
      return `${this._firstName} ${this._lastName}`;
    } else {
      return 'Missing a first name or a last name.';
    }
  }
}

// To call the getter method: 
person.fullName; // 'John Doe'

//get이 없을 경우,
//person.fullName의 결과는 [Function: fullName] 이다.
  1. get 키워드에 이어 함수를 사용한다.
  2. if..else 조건을 사용하여 _firstName과 _lastName이 모두 존재하는지 확인한다.
    (둘 다 truth 값을 반환하는지 확인) 결과에 따라 다른 값을 반환한다.
  3. this 키워드를 사용하여, 호출 된 객체의 내부 프로퍼티에 접근할 수 있다.
    fullName에서 ._firstName 과 ._lastName 모두에 엑세스하고 있다.
  4. fullName을 호출한다. 일반적으로 getter 메서드는 괄호()로 호출할 필요가 있다.
    이는, 사실 프로퍼티에 접근하고 있는 것과 같다.

getters의 이점은 다음과 같다.

  • getters는 프로퍼티를 가지고 올 때 데이터에 대한 작업을 수행할 수 있다.??
    함수를 쓸 수 있다는 것인가..
    (아마 객체내 프로피티를 데이터로 가지고 와서 작업이 가능하다는 말?)
  • getters는 조건을 사용하여 다른 값을 반환할 수 있다.
  • getter에서, 이를 이용하여 호출 된 객체의 프로퍼티에 접근할 수 있다.
  • 기능적으로 다른 개발자들이 이해하기 더 쉽다.

getter(setter) 메서드를 사용할 때 유의해야 할 점은 프로퍼티가 getter/setter 함수와 동일한
이름을 가질 수 없다는 점이다. 만약 같은 이름일 경우, 메서드를 호출시 무한 호출 스택 오류가 발생한다.
한 가지 해결 방법으로 위의 예시와 같이, 프로퍼티 이름 앞에 밑줄을 추가하는 것이다.(_)

5. setters

getter 메서드와 함꼐, 객체 내 기존 프로퍼티의 값을 재할당시키는 setter 메서드를 만들 수도 있다.

const person = {
  _age: 37,
  set age(newAge){
    if (typeof newAge === 'number'){
      this._age = newAge;
    } else {
      console.log('You must assign a number to age');
    }
  }
};

this._age에 어떤 값이 할당되어 있는지 확인할 수 있다.
setter 메서드를 통해, 숫자인 값만 this._age에 재할당한다.
재할당하기 위해 어떤 값을 사용하느냐에 따라 this._age의 출력이 달라진다.

person.age = 40;
console.log(person._age); // Logs: 40
person.age = '40'; // Logs: You must assign a number to age

age와 같은 setter 방식은 괄호()를 호출할 필요가 없다.
프로퍼티의 값을 재지정하는 것처럼 보인다. 이거 중요한거같은데.
단순히 값을 재할당하는 것이 아니라, 조건을 활용하거나? 이것저것을 활용하며 프로퍼티의 값을 재할당할 때 set을 사용해야 한다. 맞나.

getter 메서드과 마찬가지로 입력 확인, 프로퍼티 작업 수행, 객체 사용 방법에 대한 명확한 의사 표시 등
setter 메서드을 사용하는 것과 유사한 장점이 있다. ??????????????????????????????????//
Like getter methods, there are similar advantages to using setter methods that include checking input, performing actions on properties, and displaying a clear intention for how the object is supposed to be used.

setter 메서드를 사용하더라도, 직접 프로퍼티를 재할당할 수 있다.

-------뭔말이야-------------

6. Factory Functions

개별적으로 객체를 만들어 왔지만, 어떤 객체의 많은 인스턴스를 빨리 만들고 싶을 때가 있다.
(인스턴스는 일반적으로 실행 주인 임의의 프로세스,
클래스의 현재 생성된 오브젝트를 가리킨다 출처:위키백과)

여기서 factory function이 들어온다. 실제 공장은 한 품목의 여러 복제품을 빠르고 대규모로 제조한다.
factory function은 객체를 반환하는 함수로, 여러 객체 인스턴스를 만들기 위해 재사용할 수 있다.
또한 factory function 에는 반환되는 객체는 사용자가 지정할 수 있는 매개변수를 가질 수 있다.

const monsterFactory = (name, age, energySource, catchPhrase) => {
  return { 
    name: name,
    age: age, 
    energySource: energySource,
    scare() {
      console.log(catchPhrase);
    } 
  }
};

위의 mosterFactory 함수에서는 4개의 매개변수를 가지고 있으며,
name, age, energySource, scare() 라는 프로퍼티를 가진 객체를 반환한다.
ghost 와 같은 특정 몬스터를 나타내는 객체를 만들기 위해 필요한 인수를 가진
mosterFactory 함수를 호출하여 반환 값을 변수에 할당할 수 있다.

const ghost = monsterFactory('Ghouly', 251, 'ectoplasm', 'BOO!');
ghost.scare(); // 'BOO!'

monsterFactory()를 호출한 결과, ghost 객체를 갖게 되었다.
새로운 몬스터가 필요할 때마다 문자 그대로의 객체를 만들 필요는 없다.
대신, mosterFactory() 함수를 호출하면 된다.

7. Property Value Shorthand(프로퍼티 값 shorthand)

ES6에서는, destructuring(파괴)라고 알려진 변수에 프로퍼티를 할당하기 위한 몇 가지 새로운 단축키를 도입.

const monsterFactory = (name, age) => {
  return { 
    name: name,
    age: age
  }
};

이전의 연습에서, 객체를 만드는데 쓰인 factory function 을 만들었다.
키 이름이 우리가 할당했던 파라미터 이름과 같음에도 불구하고 각각의 프로퍼티에
키와 값을 할당해야만 했다.

만약, 우리가 더 많은 프로퍼티를 포함해야 한다면, 이 과정은 지루하다.
그래서 프로퍼티 가치 속기라고 불리는 파괴적인 기술을 사용하여 몇 개의 키 입력들을 구할 수 있다.??


const monsterFactory = (name, age) => {
  return { 
    name,
    age 
  }
};

프로퍼티 할당에 대해 반복할 필요가 없다는 것을 알아두자.

8. Destructured Assignment(구조화 할당)

객체에서 키-값 쌍을 추출하여 변수로 저장할 때가 있다.

const vampire = {
  name: 'Dracula',
  residence: 'Transylvania',
  preferences: {
    day: 'stay inside',
    night: 'satisfy appetite'
  }
};

residence 프로퍼티를 변수로 추출하려면 다음 코드를 사용할 수 있다.

const residence = vampire.residence; 
console.log(residence); // Prints 'Transylvania' 

그러나, 이것또한 파괴적인 할당이라는 기술을 이용하여 우리 자신을 구할 수 있다. ????????????
구조화된 할당에서 중괄호{}로 감싸진 객체의 키 이름을 가진 변수를 생성하고 여기에 객체를 할당한다.
아래 코드를 보자.

const { residence } = vampire; 
console.log(residence); // Prints 'Transylvania'

vampire 의 residence 프로퍼티를 추출하는 새로운 변수 residence를 선언한다. ?????????
Look back at the vampire object’s properties in the first code example. Then, in the example above, we declare a new variable residence that extracts the value of the residence property of vampire. When we log the value of residence to the console, 'Transylvania' is printed.
?????????????????????

구조화된 할당을 사용하여 객체의 중첩된 속성을 포착할 수도 있다.

const { day } = vampire.preferences; 
console.log(day); // Prints 'stay inside'

와 굉장히 쓸모있는 것 같은데 무슨 말인지 모르겠다.



추가 설명

getter

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Functions/get

get 구문은 객체의 프로퍼티를 그 프로퍼티로 가져올 때 호출되는 함수로 바인딩한다.
어떤 프로퍼티에 접근할 때마다 그 값을 계산하도록 해야 하거나, 내부 변수의 상태를 명시적인
함수 호출 없이 보여주고 싶을 때, 자바스크립트의 getter를 이용할 수 있다.

getter가 바인딩된 프로퍼티는 동시에 실제 값을 가질 수는 없지만, getter와 setter를 동시에
바인딩해 일종의 유사 프로퍼티(pseudo-property)를 만들 수는 있다.

다음을 유의

  • 숫자나 문자열로 구성된 식별자를 이용할 수 없다.
  • getter 는 절대로 매개변수를 가져서는 안된다.
  • 하나의 객체 리터럴에 또 다른 getter나 데이터 바인딩은 불가능하다.
    ({ get x() {}, get x() {}} 나 {x: ..., get x() {}}는 안됨)

getter는 delete 연산자를 이용해 삭제할 수 있다.

setter

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Functions/set

set syntax는 어떤 객체의 프로퍼티에 프로퍼티를 설정하려고 할 때 호출되는 함수를 바인드한다. ??
자바스크립트에서, setter는 특정한 프로퍼티에 값이 변경되어 질 때마다 함수를 실행하는데 사용될 수 있다. Setter는 유사(pseudo) 프로퍼티 타입을 생성하는 getter와 함께 가장 많이 사용된다.
실제 값을 가지는 프로퍼티와 이 프로퍼티의 setter를 동시에 갖는 것은 불가능하다.

set 문법의 유의 사항

  • 숫자 혹은 문자로된 식별자를 가질 수 있다.
  • 한 개의 매개변수만 가질 수 있다.
  • 객체 리터럴에 동인한 프로퍼티에 대한 다른 set이나 데이터 항목이 올 수 없다.
    ({set x(v) {}, set x(v) {}} 그리고 {x: ..., set x(v) {}} 는 허용되지 않는다.

setter는 delete operator를 사용하여 제거할 수 있다.

겟은 프로퍼티를 가져오는 것
셋은 프로퍼티를 설정하는 것

profile
생경하다.
post-custom-banner

0개의 댓글