티스토리 뷰

var n1 = 1;

var n2 = 1;

console.log(n1 === n2);  ?

 

var o1 = {name:'kim'}

var o2 = {name:'kim'}

console.log(o1 === o2);   ?

 

두 결과를 차이를 이해했다면, 아래에 물음에 답해보세요.

js에는 5가지의 Primitive type과 1개의 Object type으로 자료형이 구성되어 있다. primitive type을 동등 연산자

(==,===)로 비교하면 값에 의한 비교를 하게 되고 Object type으로 비교하면 참조에 의한 비교를 하게 된다.

따라서, 첫번째 콘솔에서는 true 두번째에선 false가 찍히게 된다.(o1이 가리키는 객체와 o2가 가리키는 객체는 주소값이 다르다.)

 

var personObj1 = { name: 'Alex', age: 30 }

1. 아래를 만족하는 personObj2를 생성하세요.

var personObj2 = {name:'Alex', age: 30}

console.log(personObj2);  // -> { name: 'Alex', age: 30 }

console.log(personObj1 === personObj2);  // -> false

 

2. 아래를 만족하는 함수 isEqual을 작성하세요.

function isEqual(personObj1, personObj2){

   var parr1 = Object.getOwnPropertyNames(personObj1);

   var parr2 = Object.getOwnPropertyNames(personObj2);

   if(parr1.length != parr2.length) return false;

   for(var i = 0; i<parr1.length; i++){

      if(personObj1[parr1[i]] !== personObj2[parr1[i]]) return false;

   }

   return true;

}

isEqual(personObj1, personObj2); // -> true

 

함수를 통한 파라미터의 전달에서는 어떻게 동작할까요?

-> 함수의 인자로 객체를 넘겼을때를 의미함. 

 

아래를 실행하면, 무엇이 로그에 남겨질지 한번 스스로 추측해보세요.

function changeAgeAndReference(person) {

   person.age = 25;

   person = { name: 'John', age: 50 };

   return person;

}

var personObj3 = changeAgeAndReference(personObj1); 

 

console.log(personObj1); //{name:'Alex', age: 25}

console.log(personObj3); //{name:'John', age: 50}

3. 충분히 고민 후, 코드를 실행해보고 결과의 이유를 설명해보세요.

changeAgeAndReference라는 함수에 객체를 넘겼다.

객체는 참조값에 의해 작동하기 때문에 내부에서 person.age = 25;를 실행하면 매개변수로 넘겨진 객체의 age 속성이 25로 덮어 씌워 진다.

그리고 나서 person에 새롭게 생성한 객체를 넣었고 리턴시킨후 personObj3이라는 변수에 담았다.

함수 내부에서 생성된 객체의 참조값이 리턴되었으므로 personObj3는 그 함수 안에서 생성된 객체를 가리키게 된다.

 

+ 추가

위에서 만든 isEqual이라는 함수도 사실은 객체를 정확히 비교해주지는 않는다. 다음과 같은 상황에서 잘못된 판단을 내리게 된다.

1. 두개의 객체내의 속성으로 또 객체가 내포되어 있다면?? (마찬가지로, 참조에 비교를 하게 될 것이다.)

2. 만약에 객체 내의 속성에 NaN값이 들어가있다면??

-> NaN(Not a Number)라는 값은 그 어떤 값과도 동등 비교를 할 수 없다.(무조건 false가 리턴됨)

3. 첫번째 객체에는 undefined 값을 가진 속성이 있지만, 두번째 객체에는 이러한 속성 자체가 없는 경우

-> 둘다 undefined로 판단 되기 때문에 위의 isEqual함수에 의해서는 true가 리턴될것이다.

 

그렇기 때문에, 깊은 객체 비교를 원활히 수행해주는 라이브러리를 가져다 쓰는게 좋다고 한다.

추천 :  Underscore and Lo-Dash


자바스크립트에서 데이터를 불변하게 다루기 위한 방법

Object.assign();메서드를 사용하면 객체를 복사할 수 있다. 근데, 객체 내의 프로퍼티가 값인 경우에는 제대로 복사가 되지만 객체 내의 프로퍼티로 또 객체가 나왔을때는 똑같이 참조값이 복사가 되기 때문에 위의 현상이 발생하는 것이다.

 

첫번째 예제

o2.score.concat(); 이라는 메서드를 통해 배열을 새롭게 만들고 원본 내용이 그대로 복사된 배열을 만든다음에 o2.score라는 프로퍼티에 재 할당했다. 이로써 o1의 score와 o2의 score는 전혀 다른 두 배열을 참조하고 있기 때문에 제대로 복사 되었다고 볼 수 있는것이다.

 

두번째 예제

js객체를 json으로 만들었다가 다시 js객체로 바꾸는 방법.

 

세번째 예제

객체를 freeze시킬때는 그 안에 또 객체가 있는지 주의해서 freeze시켜야함!

 

댓글
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
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
글 보관함