[러닝 자바스크립트] - 리터럴과 변수, 상수, 데이터 타입 - 2

이수빈·2022년 7월 22일
0

자바스크립트

목록 보기
2/7
post-thumbnail

러닝 자바스크립트 3장에 해당되는 부분이며, 읽으면서 자바스크립트에 대해 새롭게 알게된 것과 기록하고 싶은 부분을 정리한 내용입니다.

null과 undefined

nullundefined는 자바스크립트의 특별한 타입으로 모두 존재하지 않는 것을 나타낸다. null이 가질 수 있는 값은 null 하나이며, undefined가 가질 수 있는 값도 undefined 하나뿐이지만 둘은 서로 다른 데이터 타입으로 분리된다.

null

null은 원시값으로 값이 비어있음을 의도적으로 표현하는 것이다. undefined는 값이 지정되지 않은 경우를 의미하지만, null은 해당 변수가 어떤 객체도 가리키고 있지 않다는 것을 의미한다.

undefined

undefined는 원시값으로 선언한 후에 값을 할당하지 않은 변수나 값이 주어지지 않은 인수에 자동으로 할당된다. 이 값은 전역 객체의 속성 중 하나로, 전역 스코프에서의 변수이기도 하다.

let currentTemp; //undefined
typeof undefined //'undefined'
typeof null //'object'

저자는 변수에 직접 undefined를 할당하는 경우는 값이 주어지지 않은 변수의 동작을 고의로 흉내 내야 할 때이며, 이외에는 대부분 null을 할당하는 것이 더 나은 선택이라고 권장한다.

객체

원시 타입과 다르게, 객체는 여러 가지 값이나 복잡한 값을 나타낼 수 있으며, 변할 수도 있다. 객체에는 {와 }를 사용하는 리터럴 문법이 있으며 안의 내용이 바뀌어도 여전히 같은 객체이다.
객체의 콘텐츠는 프로퍼티 또는 멤버라고 불린다. 프로퍼티는 키와 값으로 구성되고, 프로퍼티의 이름은 문자열 혹은 심볼이어야 하며, 값은 어느 타입이든 상관이 없고 객체여도 상관 없다.

프로퍼티의 값에 접근을 할 때는 두 가지 방법이 있는데, 프로퍼티의 이름이 유효한 식별자일 경우(식별자 규칙을 지킨) . 또는 [ ]로 접근이 가능하고 프로퍼티의 이름이 유효하지 않은 식별자일 경우 [ ]로 접근이 가능하다.

const obj = {};
obj.color = "yellow";
obj["not an identifier"] = 3;

obj["not an identifier"] //3
obj.color //"yellow"
obj["color"] //"yellow"

delete obj.color; //프로퍼티 제거

Number, String, Boolean 객체

자바스크립트에는 원시 타입인 숫자와 문자열, 불리언에는 각각 대응하는 객체 타입 Number, String, Boolean이 있다. 이들 객체에는 두 가지 목적이 있는데 하나는 Number.INFINITY 같은 특별한 값을 저장하는 것이고, 다른 하나는 함수 형태로 기능을 제공하는 것이다.

const s = "hello";
s.toUpperCase(); //"HELLO" 

이는 마치 객체 프로퍼티의 값을 접근할 때 처럼 보이지만, 자바스크립트는 일시적인 String 객체를 만들고 이 임시 객체에 toUpperCase 함수를 넣는 과정이다. 자바스크립트는 함수를 호출하는 즉시 임시 객체를 파괴한다.

const s = "hello";
s.rating = 3; //일시적인 String 객체를 만들고 프로퍼티를 할당
s.rating; //자바스크립트는 임시 객체를 즉시 파괴하기 때문에 undefined

데이터 타입 변환

숫자로 바꾸기

1. Number 객체 생성자

const numStr = "33.3";
const num = Number(numStr);

이 예제는 숫자 값을 만들 뿐, Number 객체의 인스턴스를 만드는 것이 아니다.

Number()는 숫자를 다루고 표현할 때 사용하는 원시 래퍼 객체인 Number가 가지고 있는 함수이다. 따라서 Number()는 객체를 리턴하는 것이 아니라 Number를 리턴하며, new Number()가 객체로 인스턴스를 생성하여 반환하는 것이다.

const x = Number("01");
typeof x; //'number'

const x = new Number("01");
typeof x; //'object'

Number("1") === new Number("1") //false

2. parseInt, parseFloat 함수

내장 함수인 parseInt()parseFloat()Number()와 비슷하게 동작하지만, 기수를 넘겨 변환할 문자열이 몇 진수 표현인지 지정이 가능하다. 기본값은 10진수이며 숫자로 판단할 수 있는 부분까지만 변환하고, 그 뒤의 문자열은 무시된다.

const a = parseInt("16 volts",10); //16
const b = parseInt("3a",16); //58
const c = parseFloat("15.5 khp"); //15.5

참조형과 원시형

원시형

원시 값은 불변이고, 원시 값을 복사 혹은 전달할 때는 값 자체를 복사/전달한다. 즉, 원본의 값이 바뀌더라도 사본의 값이 따라서 바뀌지 않는다.

let a = 1; //원본
let b = a; //사본

a = 2; //원본 값 변경
console.log(b); //1

a === 2 //true

값 자체를 전달하기 때문에 함수 안에서 변수의 값이 바뀌어도 함수 외부에서는 바뀌지 않은 상태로 남는다.

function change(a) {
  a = 5;
}

a = 3;
change(a);
console.log(a); //3

참조형

하지만 객체는 가변이고, 객체를 복사 혹은 전달할 때는 객체가 아니라 그 객체를 가리키고 있다는 것(참조)를 복사/전달한다. 즉, 원본이 바뀌면 사본도 따라서 바뀐다.

let o = {a: 1}; //원본
let p = o; //사본

o.a = 2
o === p; //true
console.log(p) //{a: 2}

하지만 객체가 가리키는 것이 바뀌게 되면

let o = {a: 1}; //원본
let p = o; //사본

p === o; //true

o = {a: 2};
p === o; //false
console.log(p) //{a: 1}

4번째 줄에서 o에게 다른 것을 가리키라고 명령했기 때문에 p는 여전히 a:1를 가리키고 있다. 변수와 객체는 결코 일치하지 않는다.

객체는 참조를 전달하기 때문에 함수 안에서 객체를 변경하면 함수 외부에서도 변경된다.

function change_o(o) {
  o.a = 999;
}

let o = {a: 1};
change_o(o);
console.log(o); //{a: 999}
profile
내가 나중에 보려고

0개의 댓글