본문 바로가기

JavaScript

[Deep dive] 19장 프로토타입 (3)

19.12 정적 프로퍼티/메서드 

 

정적 프로퍼티/메서드 (static)

 

- 생성자 함수로 인스턴스를 생성하지 않아도 참조/호출할 수 있는 프로퍼티/메서드 

- 생성자 함수 객체가 소유한 프로퍼티/메서드 

- 생성자 함수가 생성한 인스턴스로 참조/호출할 수 없다

 

- 생성자 함수가 생성한 인스턴스는 자신의 프로토타입 체인에 속한 객체의 프로퍼티/메서드에 접근할 수 있다

- 정적 프로퍼티/메서드는 인스턴스의 프로토타입 체인에 속한 객체의 프로퍼티/메서드가 아니므로 인스턴스에 접근 불가 

 

//생성자 함수 
function Person(name) {
  this.name = name;
}

//프로토타입 메서드 
Person.prototype.sayHello = function() {
  console.log(`Hi! My name is ${this.name}`);
};

//정적 프로퍼티 
Person.staticProp = 'static prop';

//정적 메서드 
Person.staticMethod = function() {
  console.log('staticMethod');
};

const me = new Person('Lee');

//생성자 함수에 추가한 정적 프로퍼티/메서드는 생성자 함수로 참조/호출
Person.staticMethod(); //staticMethod

//정적 프로퍼티/메서드는 생성자 함수가 생성한 인스턴스로 참조/호출할 수 있다.
//인스턴스로 참조/호출할 수 있는 프로퍼티/메서드는 프로토타입 체인 상에 존재해야 한다.
me.staticMethod(); //TypeError


- 인스턴스/프로토타입 메서드 내에서 this를 사용하지 않는다면 그 메서드는 정적 메서드로 변경할 수 있음

- 메서드 내에서 인스턴스를 참조할 필요가 없다면 정적 메서드로 변경하여도 동작

function Foo() {}

//프로토타입 메서드 
//this를 참조하지 않는 프로토타입 메서드는 정적 메서드로 변경하여도 동일한 효과를 얻을 수 있다
Foo.prototype.x = function() {
  console.log('x');
};

const foo = new Foo();
//프로토타입 메서드를 호출하려면 인스턴스를 생성해야 한다
foo.x(); //x

//정적 메서드
Foo.x = function() {
  console.log('x');
};

//정적 메서드는 인스턴스를 생성하지 않아도 호출할 수 있다.
Foo.x(); //x

 

19.13 프로퍼티 존재 확인 

 

19.13.1 in 연산자 

 

 - in 연산자는 객체 내에 특정 프로퍼티가 존재하는지 여부를 확인

/*
key: 프로퍼티 키를 나타내는 문자열
object: 객체로 평가되는 표현식
*/

key in object
const Person = {
  name : 'Lee',
  address : 'Seoul'
};

//Person 객체에 name 프로퍼티가 존재 
console.log('name' in person); //true
//Person 객체에 address 프로퍼티가 존재 
console.log('address' in person); //true
//Person 객체에 age 프로퍼티가 존재하지 않음
console.log('age' in person); //false

- 확인 대상 객체가 상속받은 모든 프로토타입의 프로퍼티를 확인

- in 연산자는 person 객체가 속한 프로토타입 체인 상에 존재하는 모든 프로토타입에서 toString을 검색

console.log('toString' in person); //true

 

- ES6에서는 Reflect.has 메서드를 사용 가능 

const Person = { name: 'Lee'};

console.log(Reflect.has(Person,'name')); //true
console.log(Reflect.has(Person,'toString')); //true

 

19.13.2 Object.prototype.hasOwnProperty 메서드 

 

Object.prototype.hasOwnProperty

 

- 인수로 전달받은 프로퍼티 키가 객체 고유의 프로퍼티 키인 경우에만 true를 반환하고

- 상속받은 프로토타입의 프로퍼티 키인 경우 false를 반환

console.log(person.hasOwnProperty('name')); //true
console.log(person.hasOwnProperty('age')); //false
console.log(person.hasOwnProperty('toString')); //false

 

 

19.14 프로퍼티 열거 

 

19.14.1 for... in 문

 

- 객체의 프로토타입 체인 상에 존재하는 모든 프로토타입의 프로퍼티 중에서 프로퍼티 어트리뷰트 [[Enumerable]]의 값이 true인 프로퍼티를 순회하며 열거

for (변수선언문 in 객체) {..}

- 순회 대상 객체의 프로퍼티 뿐만 아니라 상속받은 프로토타입의 프로퍼티까지 열거 

const Person = {
  name : 'Lee',
  address: 'Seoul'
};

//in 연산자는 객체가 상속받은 모든 프로토타입의 프로퍼티를 확인
console.log('toString' in Person); //true

//for..in문도 객체가 상속받은 모든 프로토타입의 프로퍼티를 열거 
//하지만 toString와 같은 Object.prototype의 프로퍼티가 열거되지 않음
for(const key in Person) {
  console.log(key + ':' + Person[key]);
}
//name:Lee address:Seoul

- for..in문은 프로퍼티 키가 심벌인 프로퍼티는 열거하지 않음

const sym = Symbol();
const obj = {
  a:1,
  [sym]:10
};

for(const key in obj) {
  console.log(key + ':' + obj[key]); //a:1
}

- 상속받은 프로퍼티는 제외하고 객체 자신의 프로퍼티만 열거하려면 Object.prototype.hasOwnProperty 메서드를 사용하여 객체 자신의 프로퍼티인지 확인

const person = {
  name:'Lee',
  address:'Seoul',
  __proto__: {age:20}
};

for(const key in person) {
  //객체 자신의 프로퍼티인지 확인
  if(!person.hasOwnProperty(key)) continue;
  console.log(key + ":" + person[key]);
}
//name:Lee
//address:Seoul

 

19.14.2 Object.keys/values/entries 메서드 

 

- 객체 자신의 고유 프로퍼티만 열거하기 위해서는 Obejct.keys/values/entries 메서드를 사용하는 것을 권장

 

Object.keys 메서드 

- 객체 자신의 열거가능한 프로퍼티 키를 배열로 반환

const person = {
  name:'Lee',
  address:'Seoul',
  __proto__: {age:20}
};

console.log(Object.keys(person)); //[ 'name', 'address' ]

 

Object.values 메서드 

- 객체 자신의 열거 가능한 프로퍼티 값을 배열로 반환

console.log(Object.values(person)); //[ 'Lee', 'Seoul' ]

 

Object.entries 메서드 

- 객체 자신의 열거 가능한 프로퍼티 키와 값의 쌍의 배열을 배열에 담아 반환

console.log(Object.entries(person)); //[ [ 'name', 'Lee' ], [ 'address', 'Seoul' ] ]

Object.entries(person).forEach(([key,value]) => console.log(key, value));
//name Lee
//address Seoul

'JavaScript' 카테고리의 다른 글

[Deep dive] 21장 빌트인 객체  (0) 2023.08.11
[Deep dive] 20장 strict mode  (0) 2023.08.11
[Deep dive] 19장 프로토타입(2)  (0) 2023.08.10
[Deep dive] 19장 프로토타입 (1)  (0) 2023.08.10
[Deep dive] 18장 함수와 일급객체  (0) 2023.08.10