Skip to content
On this page

2020-03-02

Title
2020-03-02
Category
2020
Tags
Aliases
2020-03-02
Created
4 years ago
Updated
last year

이 글은 고현준, 송형주 님의 인사이드 자바스크립트를참조하여 작성한 글입니다.

JavaScript 데이터 타입과 연산자 (계속)

참조 타입(객체 타입)

for in 문과 객체 프로퍼티 출력

for in 문을 사용하면, 객체에 포함된 모든 프로퍼티에 대해 루프를 수행할 수 있다 .

javascript
// 객체 리터럴을 통한 foo 객체 생성
var foo = {
	name: 'foo',
	age: 30,
	major: 'computer science',
};

// for in 문을 이용한 객체 프로퍼티 출력
for (var prop in foo) {
	console.log(prop, foo[prop]);
}
// 객체 리터럴을 통한 foo 객체 생성
var foo = {
	name: 'foo',
	age: 30,
	major: 'computer science',
};

// for in 문을 이용한 객체 프로퍼티 출력
for (var prop in foo) {
	console.log(prop, foo[prop]);
}

[출력 결과]

name foo
age 30
major computer science
name foo
age 30
major computer science

for in 문이 수행되면서 prop 변수에 foo 객체의 프로퍼티가 하나씩 할당되고, prop 에 할당된 프로퍼티의 이름을 통해서 foo[prop] 와 같이 대괄호 표기법을 이용해 프로퍼티 값을 출력한다.

객체 프로퍼티 삭제

JS 에서는 객체의 프로퍼티를 delete 연산자를 이용해 즉시 삭제할 수 있다.

주의할 점은 delete 연산자는 객체의 프로퍼티를 삭제할 뿐, 객체 자체를 삭제하지는 못한다는 것이다.

javascript
// 객체 리터럴을 통한 foo 객체 생성
var foo = {
	name: 'foo',
	nickname: 'babo',
};

console.log(foo.nickname); // (출력값) babo
delete foo.nickname; // (출력값) nickname 프로퍼티 삭제
console.log(foo.nickname); // (출력값) undefined

delete foo; // (출력값) foo 객체 삭제 시도
console.log(foo.name); // (출력값) foo
// 객체 리터럴을 통한 foo 객체 생성
var foo = {
	name: 'foo',
	nickname: 'babo',
};

console.log(foo.nickname); // (출력값) babo
delete foo.nickname; // (출력값) nickname 프로퍼티 삭제
console.log(foo.nickname); // (출력값) undefined

delete foo; // (출력값) foo 객체 삭제 시도
console.log(foo.name); // (출력값) foo

참조 타입의 특성

자바 스크립트에서는 기본 타입인 숫자, 문자열, boolean, null, undefined 5가지를제외한 모든 값은 객체다. 배열이나 함수 또한 객체로 취급된다. 그리고 이러한 객체는자바스크립트에서 참조 타입이라고 부른다. 객체의 모든 연산이 실제 값이 아닌 참조값으로 처리되기 때문이다.

javascript
var objA = {
	value: 40,
};
var objB = objA;

console.log(objA.value); // 40
console.log(objB.value); // 40

objB.value = 50;

console.log(objA.value); // 50
console.log(objB.value); // 50

var a = 40;
var b = a;

console.log(a);
console.log(b);

b = 50;

console.log(a);
console.log(b);
var objA = {
	value: 40,
};
var objB = objA;

console.log(objA.value); // 40
console.log(objB.value); // 40

objB.value = 50;

console.log(objA.value); // 50
console.log(objB.value); // 50

var a = 40;
var b = a;

console.log(a);
console.log(b);

b = 50;

console.log(a);
console.log(b);

objA 는 객체 자체를 저장하고 있는 것이 아니라 생성된 객체를 가리키는 참조값을저장하고 있다.

objBobjA 를 할당할 때 참조값이 objB 에 전달되고, objBobjA 가동일한 객체를 가리키게 되어 objB.value 의 값을 50으로 갱신하자 objA.value 의값도 50으로 갱신된다.

반면 객체가 아닌 기본 타입인 a , b 의 경우는 ba 를 할당할 때, 참조값이 전달되는 것이 아니라, 값이 복사된다. 따라서 b 를 50으로 갱신해도 a 의 값은 40으로 유지된다.

Call by value vs Call by reference

객체 비교 ( == )

동등 연산자( == )를 사용하여 두 객체를 비교할 때도 객체의 프로퍼티값이 아닌 참조값을 비교한다.

javascript
var objA = {
	value: 100,
};

var objB = {
	value: 100,
};

var objC = objB;

console.log(objA.value == objB.value); // true
console.log(objA == objB); // false
console.log(objB == objC); // true
var objA = {
	value: 100,
};

var objB = {
	value: 100,
};

var objC = objB;

console.log(objA.value == objB.value); // true
console.log(objA == objB); // false
console.log(objB == objC); // true

objA.valueobjB.value 를 동등 연산자( == )로 비교하면, true 가 되는데이 둘은 기본 타입으로 값 자체를 비교하기 때문이다.

반면 objAobjB 는 같은 프로퍼티 값을 갖고 있지만, 다른 객체이기 때문에 둘의 참조값이 다르기 때문에 false 가 출력된다.

objCobjB 의 참조값을 복사해왔기 때문에, true 가 출력된다.

표준 동치 ( == ) vs 엄격 동치 ( === )

== : 두 피연산자의 자료형이 같지 않은 경우 같아지도록 변환한 후, 비교를 수행한다. 모두 객체라면 참조를 비교한다. - 숫자와 문자열 비교시엔 문자열을 숫자로 변환한다. 그리고 가장 가까운 Number *자료형 값으로 반올림한다.

  • 하나의 연산자가* Boolean 인 경우 true 는 1, false 는 0으로변환한다. - 객체를 문자열이나 숫자와 비교하는 경우, 연산자는 우선 객체의 valueOf() 또는 toString() 메서드를 이용해 문자열 혹은 숫자 값을 받으려 시도한다.

=== : 자료형 변환 없이 두 연산자가 엄격히 같은지 판별한다. 모두 객체라면 참조값 비교한다.

- 🔗 MDN web docs - 비교 연산자 에서

참조에 의한 함수 호출 방식

기본 타입과 참조 타입의 경우는 함수 호출 방식도 다르다.

기본 타입의 경우는 값에 의한 호출 방식으로 함수의 매개변수로 복사된 값이전달되기 때문에 함수 내부에서 매개변수를 이용해 값을 변경해도 실제로 호출된 변수의 값이 변경되지는 않는다.

참조 타입의 경우 참조에 의한 호출 방식으로 인자로 참조 타입인 객체를 전달할경우, 인자로 넘긴 객체의 참조값이 전달되기 때문에 함수 내부에서 참조값을 이용해서 실제 객체의 값을 변경한다.

javascript
var a = 10;
var objA = {
	value: 10,
};

function changeArg(num, obj) {
	num = 20;
	obj.value = 20;

	console.log(num); // 20
	console.log(obj.value); // 20
}

changeArg(a, objA);

console.log(a); // 10 (바뀌지 않음)
console.log(objA.value); // 20 (바뀜)
var a = 10;
var objA = {
	value: 10,
};

function changeArg(num, obj) {
	num = 20;
	obj.value = 20;

	console.log(num); // 20
	console.log(obj.value); // 20
}

changeArg(a, objA);

console.log(a); // 10 (바뀌지 않음)
console.log(objA.value); // 20 (바뀜)

Released under the MIT License.