자바스크립트 오브젝트
출처 : http://asrada2001.tistory.com/163
스쿨에 javascript 의 색다른 표현식에 관한 글이 올라왔다(by 행복한고니)
그중 new Object === {} 라는 고니님의 의견에 숨어지내리님이 급 제동을 걸어왔다.
너무나도 살벌한 분위기 속에서 결국 두 분의 논쟁에는 결론이 나질 않았고
나는 개인적으로 무소레즈님의 코멘트를 이 논쟁의 결론으로 치부한다.
무소레즈님의 댓글
---------------------------------------
1. new Object() === {} 가 같다?
2. Object 가 {} 으로 만들어진다?
3. constructor 의 비교로 객체가 똑같다고 말할수 있다?
4. Object 는 Function 의 instance 이다?
---------------------------------------
1. new Object() === {} 가 같다?
답변 1. 엄밀하게 다릅니다.
( new Object() === {} ) 의 결과는 false 입니다.
하지만 함수 객체타입은 같기에 instance 를 비교하면 true 입니다.
왜냐하면 같은 Object 함수의 객체타입으로 생성되기 때문입니다.
어떤 함수든 new 통하여 새로운 instance 개체를 생성하면
어떤 instance 개체든 Object 함수 객체타입의 instance 를 갖습니다.
예를 들어
today = new Date();
today 라는 instance 개체는
Date 함수객체타입의 instance 이기도 하지만
Object 함수 객체타입의 instance 이기도 합니다.
또한 사용자 정의 함수를 통하여 새로운 instance 개체를 생성해도 마찬가지입니다.
function funcName() {
}
fn = new funcName();
fn 이라는 instance 개체는
funcName 함수객체타입의 instance 이기도 하지만
Object 함수 객체타입의 instance 이기도 합니다.
fn 은 독립적인 instance 개체로서
funcName 이라는 함수객체에서 정의된 구조(초기환경설정)의 instance 을 가졌다는 것이지요.
만약 funcName 함수로 또다른 instance 개체를 생성한다면
fn2 = new funcName();
fn2 은 fn 과는 서로다른 instance 개체이지만
funcName 이라는 함수명으로 정의된 구조를 가진 같은 instance 를 가집니다.
fn1 과 fn2 는 같은 instance 를 가지고 있지만 서로 다른 개체입니다.
(new Object) 와 {} 에의해 생성된 각각의 instance 객체변수로 비교하자면
x1=new Object
x2=new Object
y1={};
y2={};
(x1 === x2);
(y1 === y2)
(x1 === y1);
(x2 === y2);
모두 false 입니다. 생성된 instance 개체가 서로 독립적이기 때문이지요.
하지만 instanceof 연산자를 이용하여 비교해보면 모두 같은 instance 를 가지고 있습니다.
Object 함수객체 타입은 ( Object.prototype.constructor ) 로 알아낼수 있습니다.
결과는 : function Object() { [native code] }
funcName 함수객체 타입은 ( funcName.prototype.constructor ) 로 알아낼수 있습니다.
결과는 : function funcName() { }
(new Object ) 와 {} 는 미리 정의된 Object 함수 객체를 통하여
서로다른 새로운 instance 개체들을 생성합니다.
사용자 정의 함수에서 처럼 funcName 이 없기때문에
Object 함수 객체타입의 instance 만을 갖게 되는 것입니다.
★ 그렇다고 (new Object) 와 {} 가 Object 함수객체 내부에서 주어진 정의가 완전히 같은가?
그렇지 않습니다.
{} 는 Object initializer (개체 초기화 지정자) 라고 불리우며,
Object initializer 라 불리우는 {} 를 다른 함수의 내부에서 사용시
Object initializer 를 호출할때 마다, {} 에의 정의된 속성과 그에 할당된 표현식이나 값을
매번 다시 해석(interpret) 한다는 것이 (new Object) 와 다릅니다.
함수내부에서 개체 초기화 지정자인 {} 를 정의하고
그 함수를 호출하면 {} 에의해 정의된 속성과 그 값을 다시 해석하여
매번 초기화 시킨다는것입니다.
function funcName (cond) {
A=3;
B={ A:5 };
C=new Object;
Object.prototype.A=7;
if(cond==1) return B.A;
else if( cond==2) return C.A;
else return A;
}
A1=funcName(0);
B1=funcName(1);
C1=funcName(2);
A2=funcName(0);
B2=funcName(1);
C2=funcName(2);
A1 과 A2 는 메모리에 이미 저장된 "3" 이란 값을 반환 받습니다.
C1 과 C2 도 메모리에 이미 저장된 "7" 이란 값을 반환 받습니다.
B1 과 B2 는 각각 호출시 초기화 지정자를 재 해석하여 메모리에 다시 올려 놓고,
그 후에 "5" 라는 값을 반환합니다.
B 는 초기화 지정자 {}로 할당 받았기 때문에
매번 함수를 호출 할때마다 B 의 속성과 값을 재 해석하여 메모리에 재 저장합니다.
즉, 함수를 호출할때마다 매번 다시 초기화 시킨다는 말입니다.
만약 함수 외부에서 초기화 지정자를 사용했다면
var G={ A: 9 };
G.A 를 호출할때 이미 초기화되어 메모리에 저장되어 있는 "9" 라는 값을 불러오게 됩니다.
다른 곳에서 G.A 를 호출해도 역시 이미 저장되어 있는 값 "9"를 반환합니다.
함수 내부에서 처럼 재 해석하여 재 초기화 시키는 것이 아닙니다.
C1 과 C2 를 호출하면 이미 메모리에 저정되어 있는 "7" 이라는 값을 반환합니다.
B1 과 B2 처럼 호출할때마다 재 초기화 시키는 것이 아닙니다.
그렇게 (new Object ) 와 {} 는 다릅니다.
2. Object 가 {} 으로 만들어진다?
답변 2.
{} 를 호출하면 내부에서 새로운 (new Object) 를 생성하여 instance 개체를 반환한다고 알고 있습니다.
3. constructor 의 비교로 객체가 똑같다고 말할수 있다?
답변 3.
(객체.constructor) 의 사용은 생성자가 어떤 객체타입을 가지고 있는지 참조할수 있도록
미리 정의되어 있는 Object 의 prototype 일뿐입니다.
프로그램의 처리 로직에따라 객체의 속성으로써 prototype 정의는 언제든 변경 가능하며
변경된 결과를 처리 조건에따라 필요할때 마다 활용할 수 있습니다.
(개체.constructor) 는
개체를 새로 생성했을때 그 개체가
어떤 객체 타입을 가진 생성자 함수로부터 생성된 개체인지를 참조할 수 있도록
Javascript 에서 미리 정의해둔 하나의 속성 일뿐입니다.
변경 불가한 상수가 아니란 것이지요.
프로그램 처리의 상황에따라 그 값을 변경하며, 참조하여 활용할 수 있습니다.
"constructor 의 비교로 객체가 똑같다고 말할수 있습니다."
에대해서는 그럴수도 있고 아닐수도 있겠지요.
프로그램의 처리 상황에따라 그 속성을 주어진대로 활용하거나, 변경하여 사용하거나
아니면 사용하지 않거나..
엿을 파는 엿장수 맘 아니겠습니까?
엿장수 맘대로 사용했을때 문제가 발생할 여지가 있다면야 그렇게 사용해서는 안되겠지요.
어느 분이든... 어떤 경우에 문제가 생기는지 알려주시면
저도 다음부터는 유의하여 사용해 보겠습니다.
4. Object 는 Function 의 instance 이다?
답변 4.
이미 정의되어 있는 Object 는 Function 함수 객체로부터 생성된 함수 객체이기때문에
Function 함수 객체타입의 instance 를 갖습니다.
또한 동시에 new 를 통하여 생성되기때문에 Object 객체타입의 instance 를 갖기도 합니다.