기초부터 완성까지 프런트엔드, 3장 타입 변환과 구문

HYl·2022년 3월 25일
0

3.1 변수 선언

  • 정적 언어와는 다르게 자바스크립트는 느슨한 언어(loose typing)을 가진 언어이기 때문에 데이터 타입을 따로 명시하지 않고 변수를 선언할 수 있다.
    • 느슨한 타입이라고 타입이 존재하는 것은 아니다. 변수 선언 시, 타입을 명시하지 않는 것일 뿐, 내부적으로는 데이터의 종류에 따른 변수의 타입을 가진다.
  • scope : 어떤 변수들에 접근할 수 있는지 정의한 범위
  • var : 함수 스코프
  • let const : 블록 스코프
    let & var & closure

3.2 객체와 타입

  • 자바스크립트의 값은 원시 타입(Primitive Type)객체(참조형)으로 나뉜다.
  • 원시 타입 : number string boolean null undefined Symbol Bigint
    • 원시타입은 하나의 값만 가지며, 불변 데이터이기 때문에 연산을 해도 기존 값이 변경되지 않는다.
  • 원시 타입을 제외한 나머지는 모두 객체이다.

3.2.1 Number

  • 숫자 타입은 모든 데이터를 64비트의 부동 소수점 형태로 저장하기 때문에 진정한 정수 데이터는 존재하지 않는다.

3.2.1.1. NaN

  • 자기 자신과도 동등하지 않은 결과를 반환하기 때문에 ES2015에서 추가된 Number.isNaN() 메서드를 사용해 판별하자.
a = 3 - 'a';
console.log(a === a); // false
console.log(Number.isNaN(a)); // true

3.2.1.2. 정수 범위

숫자의 범위는 Number.MAX_SAFE_INTEGETNumber.MIN_SAFE_INTEGET 사이로 정의하는 것이 좋다. 이 범위를 넘어선 숫자의 연산은 부정확할 수 있다. 이 문제를 해결하려면 ES2020에서 새로 등장한 BigInt 타입을 사용하자.

3.2.5 Symbol

심볼은 ES2015에서 도입된 원시 타입 이다. 데이터의 유일함을 나타낼 때 사용하며, 생성된 심볼은 다른 어떤 심볼과도 일치하지 않는다. 심볼은 객체가 아닌 원시 타입이기 때문에 new 키워드를 사용해 생성할 수 없다.

const sym1 = Symbol('key');
const sym2 = Symbol('key');

console.log(sym1 === sym2) // false
  • 전역 심볼 : 전역 심볼을 생성해 매번 새로운 심볼을 생성하지 않고 기존 심볼을 검색해 사용하기도 한다. Symbol.for() 메서드를 사용하여 전역 심볼을 생성한다. 다른 라이브러리들과 충돌을 피하도록 prefix를 사용해 구분하자.

3.2.5.2. 심볼의 활용

심볼은 객체나 클래스에서 유일한 프로퍼티를 만들 때 사용한다. 프로퍼티를 만들면 유일함이 보장되어 프로퍼티 추가 시 충돌을 방지한다. 또한 외부에서 직접 해당 프로퍼티에 접근할 수 없어 의도치 않은 프로퍼티 변경을 막을 수 있다.

사실 심볼로 정의한 프로퍼티를 수정할 방법이 있다. getOwnPropertySymbols() 메서드로 심볼 키 값을 얻어와서 갱신할 수 있지만 지양하길 바란다.

3.2.7.3 동적 프로퍼티 생성과 갱신

만약 객체에 프로퍼티가 존재하지 않는다면 새로운 프로퍼티가 추가되고, 있다면 기존 프로퍼티 값이 갱신된다.

getter 와 setter

어떤 프로퍼티에 접근할 때마다 동적인 계산이 필요하거나, 프로퍼티 값이 변경될 때마다 별도의 처리 코드가 필요하다면 어떨까?
이럴 때 gettersetter 접근자 프로퍼티를 사용해 일반 프로퍼티처럼 사용할 수 있다.
접근자 프로퍼티의 값에 접근하면 getter 메서드가 호출되며 이 메서드의 반환 값이 접근 표현식의 결괏값이다. 만약 접근자 프로퍼티의 값을 변경하려고 하면 setter 메서드가 호출된다.

접근자 프로퍼티는 프로퍼티의 값을 갱신할 때 유효성을 검증하거나, 조건에 따라 다른 값을 변환하는 작업들을 할 때 많이 사용한다.

const obj = {
	myName: 'javascript',
    set name(name) {
    	if (name != null) {
        	this.myName = name;
        }
    },
    get name() {
    	return this.myName;
    }
}

Object.defineProperty() 와 프로퍼티 속성

접근자 프로퍼티를 생성하는 또 다른 방법은 정적 메서드 Object.defineProperty() 를 사용하는 것이다.
이 메서드는 객체에 직접 새로운 프로퍼티를 정의하거나 이미 존재하는 프로퍼티를 수정한 후 그 객체를 반환한다.

const obj = { myName: 'javascript' };

Object.defineProperty(obj, 'name', {
  	set(name) {
      if (name !== null) {
        this.myName = name;
      }
    },
  	get() {
      return this.myName;
    },
  	writable: true, // name 프로퍼티의 수정을 허용한다
  	value: 'myName', // name 프로퍼티의 값을 설정한다.
});

첫 번째 인자로 대상이 되는 객체, 두 번째 인자로 추가 또는 갱신하려는 프로퍼티 명이나 심볼
마지막 인자로 프로퍼티 서술자 를 정의한 객체를 넘긴다.
프로퍼티 서술자에는 configurable enumerable writable value get set

3.3.5. 배열 조작

slice : 배열에서 특정 범위의 원소를 복사해 새로운 배열을 생성해 반환한다.
단, 얇은 복사를 수행하기 때문에 배열의 원소가 객체이면 참조가 유지되니 주의해야 한다.

const obj = {};
const arr = [1, obj, 3];
const newArr = arr.slice(1, 2);

// slice() 메서드는 얕은 복사를 하기 때문에 배열 내의 중첩된 객체의 참조 유지
console.log(newArr[0] === obj); // true

배열을 복사하는 또 다른 방법은 펼침 연산자 (spread operator)를 사용하는 것이다. 마찬가지로 얕은 복사를 수행한다

const arr = [1, 2, 3];
const newArr = [...arr];
console.log(newArr); // [1, 2, 3]

3.3.6 유사 배열 객체

자바스크립트에서는 일반 객체를 배열처럼 사용할 수 있다.이러한 객체를 유사 배열 객체라고 한다. 유사 배열 객체는 length 프로퍼티로 양의 정수 값을 가진 객체여야만 한다. 대표적으로는 argements 객체이다.

argument 객체는 함수에 전달한 인자를 유사 배열 객체로 만든 데이터이다.

배열이 아닌 유사 배열 객체이기 때문에 배열의 내장 메서드를 사용할 수 없다.

function foo(a, b, c) {
  console.log(arguments[0], arguments[1], arguments[2]); // 'a', 'b', 'c'
  console.log(arguments.length); // 3
  
  // 아래 코드는 TypeError가 발생한다.
  arguments.forEach((arg) => {
    	console.log(arg)
  });
}

foo('a', 'b', 'c')

TypeError가 발생할 때, 내장 메서드를 call() 또는 apply() 함수와 결합해 사용한다.

function foo(a, b, c) {  
  // 아래 코드는 TypeError가 발생한다.
  Array.prototype.forEach.call(arguments, (arg) => {
    	console.log(arg)
  });
}

foo('a', 'b', 'c')

3.5.3.2. 논리 연산자

truthy 값과 falsy 값

자바스크립트의 모든 값은 truthy 값과 falsy 값 두 가지로 나뉜다.

  • falsy : false null undefined NaN ''(빈 문자열) 0 0n
  • truthy : falsy를 제외한 모든 값이다.
profile
꾸준히 새로운 것을 알아가는 것을 좋아합니다.

0개의 댓글