[Javascript] 값과 변수(Values, Variables)

하수도키

·

2021. 11. 14. 17:06

728x90
반응형
SMALL

이번 포스팅에는 값(Value)과 변수(Variables)에 대한 차이점을 살펴보고, 원시 값과 참조 값에 데이터 할당되는 과정을 살펴보자.

원시 값과 참조값에 대한 설명은 이전 포스팅을 참조

2021.11.14 - [개발일기/Javascript] - [Javascript] 데이터 타입 정리(Data type, Primitive Value, Reference Value)

 

[Javascript] 데이터 타입 정리(Data type, Primitive Value, Reference Value)

자바스크립트 처음 공부해보면 데이터 타입이 가장 처음에 나온다. 원시값(Primitive Value), 참조값(Reference Value)으로 데이터 타입을 나눈다. 원시값, 참조값에 대해 알아보기 타입 체크하기 크게 2

hasudoki.tistory.com

아래 코드를 살펴보자.

변수 reaction[0] 을 'l'로 할당하면 reaction에 변수 값은 어떤 게 나올까?

let reaction = 'yikes';
reaction[0] = 'l';
console.log(reaction); // ??







'yikes'

reaction[0] = 'l' 코드를 실행하기 전 reaction[0] 을 console.log로 실행하면 'y'가 나온다.

그래서 reaction[0] = 'l' 실행하면 'likes'가 나온다고 기대할 수 있다.

하지만 원시값은 변경할 수 없다.

 

다음 예제를 통해 원시값과 참조값의 차이를 살펴보자.

let arr = [212, 8, 506];
let str = 'hello';

console.log(arr[0]); // 212
console.log(str[0]); // "h"

arr[0] = 420;
console.log(arr); // [420, 8, 506]

str[0] = 'j'; // ???

변수 arr을 배열로 참조값이다. 원시 값이 아니므로 조작이 가능하다.

모든 원시값들은 불변하다.(immutable) 즉, 변경되지 않는다. 읽기만 가능하다.

아래 코드를 보면 의문점이 생긴다.

원시 값은 변하지 않는다고 했는데 변하는 느낌이다?

let pet = 'Narwhal';
pet = 'The Kraken';
console.log(pet); // ?


'The Kraken'

pet에 'Narwhal'을 할당하고 다시 'The Kraken'을 할당했더니 pet값이 변했다.

원시 값은 변하지 않는다고 했더니 변한 느낌이다.

 

값과 변수와의 관계를 다시 살펴보자.

결론부터 말하자면 원시 값이 변경된 게 아니고 변수가 가리키는 값이 달라진 것이다.

변수는 와이어같이 연결해 주는 역할을 한다.

변수는 값이 아니고, 변수는 값을 가리킨다.

 

변수에 값을 할당하기

let pet = 'Narwhal'

pet 변수에 "Narwhal" 값을 할당하면 위와 같은 이미지처럼 된다.

pet 변수가 와이어처럼 "Narwhal" 값에 연결한다.

pet = 'The Kraken';

pet에 'The Kraken'을 할당하면 pet이 "Narwhal"에 연결되어있던 와이어를 "The Kraken"으로 변경한다.

 

할당 규칙

할당에서 왼쪽은 변수 pet과 같이 연결해주는 역할을 해야 한다. 값이 오면 안 된다.

20000 = 'leagues under the sea'; // Nope.
'war' = 'peace'; // Nope.

오른쪽은 반드시 표현식(expression)이 와야 한다. 그래서 항상 값이 와야 한다.

pet = count + ' Dalmatians';

 

함수에 변수 넘길 경우?

function double(x) {
  x = x * 2;
}

let money = 10;
double(money);
console.log(money); // ?

console.log의 값은 10이다.

double(money)을 실행하면 money 변수가 전달되어 double 함수 안에서 x = x * 2; 를 실행하면 money변수의 값이 20으로 변할 거라 생각된다.

하지만, double(money)가 실행될 때 money 변수의 값을 파악한 후 값이 전달된다.

즉, money변수 대신 값인 10이 전달된다. 따라서, double함수가 실행된 후에도 money의 변수의 값은 그대로 10이다.

 

결론

1. 원시 값은 불변하다.(immutable)

2. 변수는 값이 아니다.

3. 변수는 값을 가리키는 와이어 역할을 한다.

 

참고 1.

원시 값과 참조값의 조작 여부 함수 살펴보기

- 원시값 조작 여부

import feed from './feed.js';

let pets = 'Tom and Jerry';
feed(pets);
console.log(pets[0]);

console.log 결과는 'T'이다. 만약 feed 함수를 실행하고 pets[0]에 값을 'T'가 아닌 다른 값을 변경할 수 있을까?

결과는 정상적인 방법으로는 불가능하다. 위에서 살펴봤듯이 변수 pets를 넘기는 게 아니고 값인 'Tom and Jerry'를 feed 함수에 전달하기 때문이다.

문자열은 불변이기 때문에 변경할 수가 없다.

아래 코드처럼 console.log 로직을 변경하면 가능하지만 이건 매우 비정상이다.

export function feed(pets) {
  // Overwrite console.log with a fake implementation
  // so that you call it when you try to log "T"!
  let realLog = console.log;
  console.log = function(message) {
    realLog('You got pranked!');
  };
}

참조값 조작 여부

import feed from './feed.js';

let pets = ['Tom', 'Jerry'];
feed(pets);
console.log(pets[0]);

console.log의 결괏값은 'Tom'이다.

여기서도 feed(pets)를 실행하면 pets[0]의 결괏값을 변경할 수 있을까?

답부터 말하자면 변경 가능하다.

계속 반복하듯이 말하지만 변수가 전달되지 않고 함수에 값이 전달된다.

즉 ['Tom', 'Jerry']가 전달된다.

원시 값 string과 달리 참조값 array는 조작이 가능하다.(변이 mutable)

 

export function feed(pets) {
  pets[0] = 'Pikachu';
}

첫 번째 코드에 let pets와 두 번째 코드의 인자 pets는 다르다. 변수가 아닌 값으로 전달되었기 때문이다.

다르지만 그들은 동일한 배열을 가리키고 있기 때문에 한 곳에서 변경하면 코드의 다른 값에서도 변경된 게 적용된다.

이 부분은 다음 포스팅 때 데이터 할당할 때 메모리 관련 포스팅으로 자세하게 설명하겠다.

728x90
반응형
LIST