자바스크립트

[Javascript] 참조 타입의 특성

포포015 2021. 1. 18. 10:46

자바스크립트에서 기본 타입인 숫자,문자열,불린값,null,undefined 5가지를 제외한 모든 값은 객체이다.

"배열"이나 "함수" 또한 객체로 취급된다.( 이러한 객체는 JS에서 참조 타입이라고 부른다)

이것은 객체의 모든 연산이 실제값이 아닌 참조 값으로 처리 되기때문이다.

1
2
3
4
5
6
7
8
9
10
11
12
//객체 생성
var objA = {
  val: 40,
};
var objB = objA;
 
console.log(objA.val); //출력값 40
console.log(objB.val); //출력값 40
 
objB.val = 50;
console.log(objA.val); //출력값 50
console.log(objB.val); //출력값 50
cs

objA 변수는 객체 자체를 저장하는게 아니라, 생성된 객체의 주소값을 저장하고 있음

 

* 객체 비교

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

1
2
3
4
5
6
7
8
9
10
11
var a = 100;
var b = 100;
 
var objA = { value: 100 };
var objB = { value: 100 };
var objC = objB;
 
console.log(a == b); //출력값 true
console.log(objA == objB); //출력값 false
console.log(objB == objC); // 출력값 true
 
cs

1) a과 b는 숫자 100을 저장하고 있는 기본타입의 변수이다. 기본타입의 경우 동등연산자(==)를 이용해 비교할때

값을 비교한다

2) 기본타입의 경우는 값자체를 비교해서 판단하지만, 객체와 같은 참조타입의 경우는 참조값(주소값)이 같아야 true이다

 

* 참조에 의한 함수 호출 방식

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

기본타입 - 값에의한호출(Call by value) ,즉 함수를 호출할때 기본타입의 값을 넘길경우 호출된 함수의

            매개변수로 복사된값이전달된다(때문에 함수내부에서 매개변수를 이용해 값변경해도 호출된 변수의 값 변경X)

참조타입 - 참조에의한호출(Call by Reference) ,즉 함수를 호출할때 참조타입의 객체를 전달할 경우 ,

             기본타입과 다르게 매개변수로 복사되지않고. 객체의 참조값이 그대로 함수내부에 전달(객체의 값 변경 O)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var a = 100;
var objA = { value: 100 };
 
function changeArg(num, obj) {
  num = 200;
  obj.value = 200;
 
  console.log(num); //출력 100
  console.log(obj); // 출력 200
}
 
changeArg(a, objA);
 
console.log("변수 " + a); //출력 100
console.log("객체 objA의 값" + objA.value); //출력 200
 
csa

함수 내부에서 매개변수 num과 obj 를 이용해 인자로 전달된 a와 obj.value 값을 바꿧지만

참조타입인 객체 objA.value 의 프로퍼티만이 실제값이 변했다 ( 이와같이 기본타입은 변경 X)

 

* 프로토 타입

자바스크립트의 모든 객체는 자신의 부모 역할을 하는 객체와 연결되어 있다.

 (이것은 마치 객체 지향의 상속 개념과 같이 부모의 프로퍼티를 자신의것처럼 쓸수 있다)

이러한 부모 객체를 자바스크립트에서는 프로토타입 객체( 짧게는 프로토타입) 이라고 부른다

1
2
3
4
5
6
7
8
9
var kim = {
  name: "kim",
  age: 30,
};
 
console.log(kim.toString());
 
console.dir(kim);
 
cs
위 코드의 출력

위와 같은 코드는 kim 객체를 생성하고 toString 메서드를 호출한것이다.

그러나 kim객체는 toString 메서드를 선언안했는데 어떻게 썻을까?

- kim 객체의 프로토타입에 기본메서드로 정의 되어있었고 kim객체가 상속처럼 호출했기때문

_proto_ 프로퍼티에 이미 object가 있다.( 모든 객체는 자신의 프로토타입을 가리키는 숨겨진 프로퍼티를 가진다)

_proto_ 프로퍼티가 가리키는 객체가 Object.prototype 이며 모든객체에서 호출가능한 JS 기본 내장 메서드가 포함됨.

 

* 배열 

배열은 JS객체의 특별한 형태이다. C나 자바처럼 같은기능을 하는객체지만 굳이 이들과 다르게 

굳이 크기를 지정하지않아도되며, 어떤위치에 어느타입의 데이터를 저장하더라도 에러 발생하지않음

 

* 배열 리터럴 생성 

객체 리터럴 생성은 { } 를 이용한 표기법이라면 , 배열 리터럴 생성은 대괄호 [ ] 를 사용한다 (접근도 인덱스 번호로)

1
2
3
4
5
6
 
var color = ["red", "blue", "orange", "green"];
console.log(color[0]); // 출력값 red
console.log(color[1]); // 출력값 blue
console.log(color[2]); // 출력값 orange
 
cs

 

* 배열의 요소 생성

객체가 동적으로 프로퍼티를 추가 할수 있듯이, 배열도 동적으로 배열원소를 추가 할수 있다

 JS 배열의 경우는 값을 순차적으로 넣을 필요없이 아무 인덱스 위치에나 값을 동적으로 추가 가능

 

1
2
3
4
5
6
7
8
9
10
11
// 빈배열 생성
var emptyArr = [];
console.log(emptyArr[0]); // 출력값 undefined
 
//배열 요소 동적 생성
emptyArr[0] = 100;
emptyArr[3] = "kim";
emptyArr[7] = true;
console.log(emptyArr); // 출력값 100, empty x 2 , kim , empty x3 , true
console.log(emptyArr.length); // 출력값 8
 
cs

1) js가 배열의 크기를 배열의 인덱스중 가장 큰값으로 정하기때문에 길이는 8으로 나온다

 

* 배열 표준 메서드와 length 프로퍼티

JS는 배열에서 사용가능한 다양한 표준메서드를 제공한다. 예를들어 push() 메서드는 

인수로 넘어온  항목을 배열의 끝에 추가하는 JS 표준 배열 메서드이다.(length 값 위치에 새로운 원소값 추가)

 

1
2
3
4
5
6
7
8
9
10
11
12
// arr 배열 생성
var arr = ["zero", "one", "two"];
 
// push () 메서드 호출
arr.push("three");
console.log(arr); // 출력값 ['zero','one','two','three'];
 
// length 값 변경후 , push 메서드 호출
arr.length = 5;
arr.push("four");
console.log(arr); // 출력값 ['zero','one','two',empty,'three'];
 
cs

 

* 배열의 프로퍼티 동적 생성

배열도 자바스크립트의 객체이므로 , 객체처럼 동적으로 프로퍼티를 추가할수 있다

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 
// 배열생성
var arr = ["zero", "one", "two"];
console.log(arr.length); //출력값 3
 
//프로퍼티 동적 추가
arr.color = "blue";
arr.name = "number_array";
console.log(arr.length); //출력값 3
 
//배열 원소 추가
arr[3] = "red";
console.log(arr.length); // 출력값 4
 
//배열 객체 출력
console.dir(arr); // arr 배열의 모든 프로퍼티를 출력한 결과
cs

1) 프로퍼티를 추가해도 (동적 프로퍼티가 추가되어도 length 값은 변경되지않음)

 

* 배열 요소 삭제

배열도 객체이므로 , 배열 요소나 프로퍼티를 삭제하는데 delete 연산자를 사용할수 있다.

 (delete 연산자는 해당요소의값을 지워줄뿐 공간자체를 삭제하지않는다)

1
2
3
4
5
var arr = ["A", "B", "C", "D"];
delete arr[2];
console.log(arr); // 출력값 A,B,empty,D
console.log(arr.length); //출력값 4
 
cs

 

* 기본타입과 표준메서드

JS 는 숫자,문자열,불린값에 대해 타입별로 호출가능한 표준 메서드를 정의하고 있다.

하지만 기본타입의 경우 객체가 아닌데 메서드를 호출할수 있는이유는 

기본값은 메서드 처리 순간에 객체로 변환된 다음 > 각타입별 표준 메서드 를 호출하게 되고

메서드 호출이 끝나면 다시 기본값으로 복귀하게된다 ( 기본타입이지만 정의된 표준메서드를 객체처럼 호출가능)

 

* + 연산자

+ 연산자는 더하기 연산과 , 문자열 연결 연산을 수행한다 

 

* ==(동등)연산자와 ===(일치) 연산자

== 연산자는 비교하려는 피연산자의 타입이 다를경우에 타입변환을 거친다음 비교

=== 연산자는 피연산자의 타입이 다를경우 타입을 변경하지 않고 비교

* !! 연산자

JS 프레임워크 소스를 분석하다보면 !! 와같은경우가 있는데 이 역할은 피연산자를 불린값으로 변환