Back Ground

Object 객체 본문

Javascript

Object 객체

Back 2018. 10. 7. 20:08


사실 Object 그 자체도 객체다. 

모든 객체의 최종 prototype이기도 하다


예시를 하나 들어 객체의 prototype이 뭔지 보자면

이미 구현된 객체의 prototype을 확인할 때는 __proto__를 사용한다.




prototype 은 Function 객체의 속성입니다. 이 함수로 생성 된 객체의 프로토 타입입니다.

__proto__ 는 프로토 타입을 가리키는 객체의 내부 속성입니다. 

현재 표준은 동등한 Object.getPrototypeOf(O) 메소드를 

제공하지만 사실상 __proto__ 표준은 더 빠릅니다.


함수의 prototype 과 객체의 __proto__ 체인을 비교하여 instanceof 관계를 찾을 수 있으며 prototype 을 변경하여 이러한 관계를 깨뜨릴 수 있습니다.

function Point(x, y) {
    this.x = x;
    this.y = y;
}

var myPoint = new Point();

// the following are all true
myPoint.__proto__ == Point.prototype
myPoint.__proto__.__proto__ == Object.prototype
myPoint instanceof Point;
myPoint instanceof Object; 

여기서 Point 는 생성자 함수이며, 절차 적으로 객체 (데이터 구조)를 만듭니다. myPoint  Point() 의해 생성 된 객체이므로 Point.prototype 은 그 시점에 myPoint.__proto__에 저장됩니다. 


출처 : https://code.i-harness.com/ko-kr/q/97f92f


prototype 함수이고 

__proto__ 는 속성 

prototype는 __proto__생성 함수란 걸 알 수 있다.



예시를 하나 들어 객체의 prototype이 뭔지 보냐면

 이미 구현된 객체의 prototype을 확인할 때는 __proto__를 사용한다.

1
Math.__proto__; // Object { ... }
cs


확인한 결과 Object 객체 란걸 알게 되었다.

이렇게 생성자를 통해 만든 객체의 prototype의 prototype도 Object 객체이다.


1
2
3
4
5
6
7
function Person(name) { this.name = name; }
Person.prototype.sayHello = function() {
  alert(this.name);
};
var zero = new Person('zero');
zero.__proto__; // { sayHello: function() }
zero.__proto__.__proto__; // Object { ... }
cs




Object 객체 자체의 prototype 없다.

1
Math.__proto__.__proto__; // null
cs

Object가 최종이기 때문이다.

Object 객체의 생성자는 window 객체에 저장되어 있다.



모든 객체가 Object 객체로부터 상속받기 때문에 모든 객체는 Object 객체의 메소드들을 사용










Object


객체.hasOwnProperty(속성명)

객체의 속성이 상속받지 않은 속성인지 알려준다

자신의 속성이면 true, 

부모의 속성이거나 아예 속성이 아니면 false를 반환한다.


1
2
3
4
5
6
7
var obj = {
  example: 'yes',
};
obj.example; // yes
obj.hasOwnProperty('example'); // true
obj.toString; // function toString() { [native code] }
obj.hasOwnProperty('toString'); // false
cs





객체.isPrototypeOf(대상)

객체가 대상의 조상인지 알려준다.


1
2
3
4
5
6
7
8
9
10
11
var GrandParent = function() { };
 
var Parent = function() { };
Parent.prototype = new GrandParent();
 
var Child = function() { };
Child.prototype = new Parent();
 
var child = new Child();
Parent.prototype.isPrototypeOf(child); // true
GrandParent.prototype.isPrototypeOf(child); // true
cs






Object.getPrototypeOf(객체), Object.setPrototypeOf(객체, prototype)

객체의 prototype을 조회하거나 설정할 수 있다.


1
2
3
Object.getPrototypeOf(child); // GrandParent
Object.getPrototypeOf(new GrandParent()); // 빈 객체 { }
Object.setPrototypeOf(child, new Parent());
cs



instanceof

객체가 특정 생성자의 자식인지 조회할 수 있다.

1
2
child instanceof Parent; // true
child instanceof GrandParent; // true
cs





객체.propertyIsEnumerable(속성)

해당 속성이 열거 가능한 속성인지 알려준다. 

열거 가능이란 for ... in과 같은 반복문 안에서 쓸 수 있는지를 말한다.

상속받은 속성과 해당 객체의 속성이 아닌 것은 기본적으로 제외된다.


1
2
3
4
5
6
var a = [false1'2'];
a.propertyIsEnumerable(0); // true
a.propertyIsEnumerable('length'); // false
for (var value in a) {
  console.log(value); // 0, 1, 2
}
cs






객체.toString

가끔 객체를 alert하거나 console.log할 때 원하는 결과는 안 나오고,

 [object Object] 이런 게 나올 때가 있다.

 내부적으로 toString 메소드가 호출된 결과다.

 문자열끼리 더할 때 주로 호출된다.

 기본적으로는 객체의 종류를 알려주고, 사용자가 임의로 바꿀 수 있다.


1
2
3
4
5
6
7
8
var obj = { a: 'hi', b: 'zero' };
obj.toString(); // [object Object]
Math.toString(); // [object Math]
obj.toString = function() {
  return this.a + ' ' + this.b;
}; // 임의로 바꿈
obj.toString(); // 'hi zero';
obj + ' cho'// 'hi zero cho'
cs







객체.valueOf

객체의 기본 값을 의미한다. 

숫자 계산을 할 때 내부적으로 호출된다.

toString처럼 내부적으로 호출되기 때문에 관리하기 어렵다.


1
2
3
4
5
6
7
var obj = { a: 'hi', b: 'zero' };
obj.valueOf(); // { a: 'hi', b: 'zero' }
obj + 5// '[object Object]5' <-- 내부적으로 toString이 호출됨
obj.valueOf = function() {
  return 3;
}
obj + 5// 8 <-- 내부적으로 valueOf가 호출됨
cs







Object.create(prototype, 속성들)

객체를 생성하는 방법 중 하나다. 
속성들 부분은 writable, configurable, enumerable, get, set ,value의 옵션이 있는데 
아래 defineProperties를 참고하면 좋다.

1
2
3
4
5
6
7
8
9
var obj = {}; // Object.create(Object.prototype); 과 같음
var obj2 = Object.create(null, {
  a: {
    writable: true,
    configurable: false,
    value: 5,
  }
});
obj2.a; // 5
cs






Object.defineProperties(객체, 속성들), Object.defineProperty(객체, 속성, 설명)

객체의 속성을 자세하게 정의할 수 있다.

속성의 설명을 따로 설정할 수 있는데, 

writable은 속성값을 변경할 수 있는지, 

enumerable은 for ... in 반복문 안에서 사용할 수 있는지, 

configurable은 속성의 설명을 바꿀 수 있는지를 설정다. 

false인 경우 delete 동작도 불가능하다. 

기본적으로 writable, enumerable, configurable은 false이다. 

value는 속성의 값, get은 속성의 값을 가져올 때, set은 속성의 값을 설정할 때를 의미이다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
var obj = {};
Object.defineProperties(obj, {
  a: {
    value: 5,
    writable: false,
    enumerable: true,
  },
  b: {
    get: function() {
      return 'zero';
    },
    set: function(value) {
      console.log(this, value);
      this.a = value;
    },
    enumerable: false,
    configurable: false,
  },
});
obj.a; // 5
obj.b; // 'zero'
obj.a = 10;
obj.a; // writable이 false라 그대로 5
for (var key in obj) {
  console.log(key); // b의 enumerable이 false이니까 a만 log됨
}
obj.b = 15// 15로 설정되는 대신 set의 내용이 실행됨. set의 value는 15
obj.a; // this.a = value로 인해 15로 바뀌어야 하나 writable이 false라 무시됨
obj.b; // 그대로 'zero'
Object.defineProperty(obj, 'b', {
  value: 5
}); // Uncaught TypeError: Cannot redefine property: b
cs

마지막은 configurable이 false기 때문에 b 속성의 설명을 재정의할 수 없다.



1
2
3
4
5
6
7
8
9
10
Object.defineProperty(obj, 'c', {
  value: { x: 3, y: 4 },
  writable: false,
  enumerable: true,
});
obj.c; // { x: 3, y: 4 }
obj.c = 'zero';
obj.c; // writable이 false라 그대로 { x: 3, y: 4 }
obj.c.x = 5// 값이 객체인 경우 그 객체의 속성을 바꿈
obj.c; // { x: 5, y: 4 }로 바뀜
cs


writable은 속성 값을 바꾸는 것을 막지만 만약 속성의 값이 객체인 

경우에는 그 객체 안의 속성을 바꾸는 것은 막지 못한다. 

바꾸는 것을 전체적으로 막기 위해서 Object.freeze 메소드가 있다.





출처 : https://www.zerocho.com/category/JavaScript/post/573dbc9370ba9c603052cc9a


'Javascript' 카테고리의 다른 글

Javascript - 틸트 연산자 (~) 물결 / (~~)  (0) 2019.03.11
고차 함수(Currying 커링)  (0) 2018.11.28
객체 지향 프로그래밍(생성자와 프로토타입)  (0) 2018.10.04
Date, RegExp 객체  (0) 2018.10.04
JavaScript 핵심요약  (0) 2017.12.22
Comments