예를들어 아래와 같은 코드를 보자.
var str = "string";
str[0]= "S";
console.log(str); //내 예상값 : String
하지만 내 예상과는 다르게 string으로 출력이 되었다.
이게 왜 이럴까 하며 javascript에 대해 공부를 해보았다. 그 이유는 바로 원시값은 변경 불가능한 값!!!이기 때문이었다.
숫자, 문자열, 불리언, null, undefined, 심벌, 객체 타입
1. 원시타입 : 숫자, 문자열, 불리언, null, undefined, 심벌 타입
2. 객체 타입: 객체, 함수, 배열 등...
먼저 문자열은 유사배열객체 이면서 이터러블 이므로 배열과 유사하게 각 문자에 접근 할 수있다.
하지만 문자열은 원시 값이므로 변경할 수 없다는 사실을 알게 되었다. 또한 이 과정에서 에러는 발생하지 않는다는 사실도 알게 되었다.
이처럼 일부 문자를 변경해도 문자열은 읽기 전용 값이므로 변경할 수 없다.
하지만!!!!
변수에 새로운 문자열을 재할당하는 것은 가능하다.
왜냐하면 기존 문자열을 변경하는 것이 아니라 새로운 문자열을 새롭게 할당하는 것이기 때문이다.
이처럼 Javascript에서 원시 값은 변경 불가능한 값이기 때문에 값을 직접 변경할 수 없다.
변수 값을 변경하기위해 원시 값을 재할당하면 새로운 메모리 공간을 확보하고 재할당 값을 저장한 후, 변수가 참조하던 메모리 공간의 주소를 변경한다.
이러한 특성을 불변성이라고 한다.
즉, 불변성을 갖는 원시 값을 할당한 변수는 재할당 이외에 변수 값을 변경할 수 있는 방법이 없다.
그렇다면 아래의 코드는 어떻게 동작을 할까?
var str = "string";
str= "STRING";
console.log(str); //내 예상값 : STRING
이 경우 내 예상대로 잘 동작한다.
위에서 설명한 바와 같이 문자열을 새롭게 재할당 하는 것이기 때문이다.
추가적으로 정말 많이 헷갈릴 수 있다고 생각한 부분을 적으려고 한다.
값에 의한 전달 이라는 부분이다.
var a = 80;
var b = a;
console.log(a, b); //80 80
console.log(a === b); // T
a = 100;
console.log(a, b); //100 80
console.log(a === b); // F
위의 코드는 //(주석)의 내용과 같이 동작한다.
처음에는 헷갈렸다. a=b이고 a의 값에 재할당을 했다면 b에도 재할당이 되어 b=100이 되지 않을까? 라는 생각을 했다.
하지만 값에 의해 전달된 값은 다른 메모리 공간에 저장된 별개의 값이므로 어느 한쪽에서 재할당을 통해 값을 변경하더라도 서로 간섭할 수 없다.
참고로 파이썬은 변수에 원시 값을 갖는 변수를 할당하는 시점에는 두 변수가 같은 원시 값을 참조하다가 어느 한쪽의 변수에 재할당이 이뤄졌을 때 새로운 메모리 공간에 재할당된 값을 저장하도록 동작할 수 있다.
그러므로 위의 코드와 값이 동작하는 것이다.
값에 의한 전달 이란 용어는 자바스크립트를 위한 용어가 아니므로 엄격하게 표현하면 변수에는 값이 전달되는 것이 아니라 메모리 주소가 전달된다. 이는 변수와 같은 식별자는 값이 아니라 메모리 주소를 기억하고 있기 때문이다.
즉, 값에 의한 전달도 사실은 값을 전달하는 것이 아니라 메모리 주소를 전달한다. 단, 전달된 메모리 주소를 통해 메모리 공간에 접근하면 값을 참조할 수 있다.
이렇게 원시 값에 대해 알아보았다. 처음에는 많이 헷갈렸지만 그래도 어느정도 개념이 잡힌 것 같다. 이를 공부하면서 객체에 대한 공부도 해야겠다는 생각을 했다. 다음 포스팅에는 객체에 대해 다뤄봐야 겠다.