[FE Study] Javascript - (3)

365.48km·2023년 1월 2일
0

[FE Study] JavaScript

목록 보기
3/5
post-thumbnail

1. 자바스크립트의 타입의 종류와 number 타입이 다른 언어와의 차이점은?

  • 다른 언어에는 int, double 등 숫자타입의 다양함이 있지만, JavsScript는 number는 하나만 있다.
  • 정수만을 위한 타입이 없고, 모든 수를 실수로 처리한다.

Key Ponint 💡 자바스크립트의 원시 타입은 몇가지인가? 종류는?

  • boolean, string, number, undefined, null, symbol 이렇게 6가지 종류가 있다.
    ( undefined선언만 되어있고 값은 없는 상태이며, null자료형이 객체이며 빈 값을 의미한다. )

2. undefined와 null의 차이점

Key Ponint 💡 undefined는 개발자가 의도적으로 할당하기 위한 값이 아니라, 자바스크립트 엔진이 변수를 초기화할 때 사용하는 값을 의미한다.

  • 따라서, 변수를 참조했을때 undefined가 반환된다면 초기화하지 않은 변수라는 것을 알 수 있다.

Key Ponint 💡 null은 변수에 값이 없다는 것을 의도적으로 명시할 때 사용

  • (의도적 부재) 이는 이전에 할당되어 있던 값에 대한 참조를 명시적으로 제거하는 것을 의미한다.
  • 자바스크립트 엔진은 누구도 참조하지 않는 메모리 공간에 대해 가비지 콜렉션을 수행한다.

3. 변수 초기화란?

Key Ponint 💡 변수를 사용하려면 초기화(Initialize)를 해야한다.

  • 변수는 변수를 선언한 후 값 할당해주어야만 사용할 수 있다.
  • 경우에 따라 초기화를 하지 않고도 사용할 수 있지만 기본적으로는 변수는 선언과 초기화가 이루어져야 사용할 수 있다.
// 변수 선언
let message;

// 변수 초기화
message = "Hello World";

// 변수 선언 및 초기화
let other_message = "Hello World";

4. 데이터 타입이 필요한 이유

  • 값을 저장할 때 확보해야 하는 메모리 공간의 크기를 결정하기 위해서
  • 값을 참조할 때 한 번에 읽어들어야 할 메모리 공간의 크기를 결정하기 위해서
  • 메모리에서 읽어 들인 2진수를 어떻게 해석할지 결정하기 위해서

5. ==와 ===의 차이점

Key Ponint 💡 동등 비교(==) 연산자는 좌향과 우향의 암묵적 타입 변환을 통해 타입을 일치시킨 후, 같은 값인지 비교한다.

  • 따라서 타입이 다르더라도 암묵적 타입 변환 후에 같은 값이라면 true를 반환한다.

Key Ponint 💡 일치 비교(===) 연산자는 좌항과 우항의 피연산자가 타입이 같고, 값이 같은 경우에 한하여 true를 반환한다.

  • 따라서, 타입이 다르면 false를 반환한다.

6. 타입 변환이란? (명시적 타입 변환 vs 암묵적 타입 변환)

Key Ponint 💡
타입변환은 대표적으로 명시적 타입과 암묵적 타입으로 나눌 수 있다.

  • 명시적 타입 변환 : 개발자가 의도적으로 타입을 변환하는 것. 타입 캐스팅(Type Casting) 이라고도 함.
  • 암묵적 타입 변환 : 개발자의 의도와는 상관없이 자바스크립트 엔진에 의해 암묵적으로 타입이 자동으로 변환되는 것. 타입 강제 변환(Type Coercion)이라 한다.

6.1. 명시적 형변환(Explicit Type Conversion)이란?

Key Ponint 💡
명시적 형변환이란 사용자가 직접 데이터의 타입을 변경하는 것이다. 표준 빌트인 생성자 함수(String, Number, Boolean)를 new 연사자 없이 호출하는 방법, 빌트인 메서드 사용 방법 등이 있다.

1) 문자열 타입으로 변환

// 1. String 생성자 함수를 new 연산자 없이 호출하는 방법
// 숫자 타입 => 문자열 타입
console.log(String(1));        // "1"
console.log(String(NaN));      // "NaN"
console.log(String(Infinity)); // "Infinity"
// 불리언 타입 => 문자열 타입
console.log(String(true));     // "true"
console.log(String(false));    // "false"

// 2. Object.prototype.toString 메소드를 사용하는 방법
// 숫자 타입 => 문자열 타입
console.log((1).toString());        // "1"
console.log((NaN).toString());      // "NaN"
console.log((Infinity).toString()); // "Infinity"
// 불리언 타입 => 문자열 타입
console.log((true).toString());     // "true"
console.log((false).toString());    // "false"

// 3. 문자열 연결 연산자를 이용하는 방법
// 숫자 타입 => 문자열 타입
console.log(1 + '');        // "1"
console.log(NaN + '');      // "NaN"
console.log(Infinity + ''); // "Infinity"
// 불리언 타입 => 문자열 타입
console.log(true + '');     // "true"
console.log(false + '');    // "false"

2) 숫자 타입으로 변환

Key Ponint 💡
1. Number 생성자 함수를 new 연산자 없이 호출하는 방법
2. pareInt, parseFloat 함수를 사용하는 방법
3. + 단항 산술 연산자 사용 방법
4. * 산술 연산자 사용 방법

// 1. Number 생성자 함수를 new 연산자 없이 호출하는 방법
// 문자열 타입 => 숫자 타입
Number('0') // 0
Number(true) // 1
Number(false) // 0


// 2. pareInt, parseFloat 함수를 사용하는 방법(문자열만 변환 가능)

parseInt('0') // 0
parseInt('-1') // -1

parseInt(true) // NaN

// 3. + 단항 산술 연산자 이용방법
// 문자열 타입 => 숫자 타입
+'0' // 0
+'-1' // -1

// 불리언 타입 => 숫자 타입
+true // 1
+false // 0

// 4. *산술 연산자 이용방법
// 문자열 타입 => 숫자 타입
'0' * 1 // 0

// 불리언 타입 => 숫자 타입
true * 1 // 1
false * 1 // 0

6.2. 암묵적 타입(타입 강제 변환)

Key Ponint 💡
개발자의 의도와는 상관없이 표현식을 평가하는 도중에 자바스크립트 엔진에 의해 암묵적으로 타입이 자동 변환되는 것

1) 문자열 타입 변환

Key Ponint 💡

  • '+' 연산자는 피연산자 중 하나가 문자열이면 문자열 연결 연산자로 동작한다.
console.log("10" + 1); // '101'
console.log(10 * "10"); // 100

const abc = 1
abc + '' // '1' : 숫자형 타입에서 문자형 타입으로 형변환

console.log(2 + "1" + 5); // 215
console.log(1 + 2 + "1" + 5); // 주의 : 315 


0 + '' // '0'
-0 + '' // '0'
NaN + 'a' // NaNa
Infinity + '' // 'Infinity'
-Infinity + '' // '-Infinity'

true + '' + false + '' // 'truefalse'

[] + '' // ''
[1,2] + '' // '1,2'
[[1,2],[3,4]] + '' // '1,2,3,4'

({}) + '' // '[object Object]'


Symbol() + '' // TypeError 
  • Symbol()은 string 타입으로 변환할 수 없다.

2) 숫자 타입으로 변환

Key Ponint 💡

  • '+' 단항 연산자는 피연산자가 숫자 타입의 값이 아니면, 숫자 타입의 값으로 암묵적으로 타입 변환을 수행한다.
1 - '1' // 0


// 문자열 타입 => 숫자 타입
+'' // 0
+'0' // 0
+'1' // 1
+'hello' // NaN

// 불리언 타입 => 숫자 타입
+true // 1
+false // 0

// null 타입 => 숫자 타입
+null // 0

// undefined => 숫자 타입
+undefined // NaN

// 객체 타입 => 숫자 타입
+[] // 0
+[1,2] // NaN
+function(){} // NaN

Key Ponint 💡
자바스크립트 엔진은 불리언 타입이 아닌 값을 Truthy값(참으로 평가되는 값) 또는 Falsy값(거짓으로 평가되는 값)으로 구분한다.

*false로 평가되는 Falsy값

  • false
  • undefined
  • null
  • 0,-0
  • NaN
  • ''(빈 문자열)

7. 단축 평가

Key Ponint 💡
논리 연산의 결과를 결정하는 피연산자를 타입 변환하지 않고 그대로 반환하는 것.
즉, 표현식을 평가하는 도중에 평가 결과가 확정된 경우 나머지 평가 과정을 생략하는 것을 말한다.

7.1. 논리 연산자를 사용한 단축 평가

// 논리곱
'Cat' && 'Dog' // 'Dog'

// 논리합
'Cat' || 'Dog' // 'Cat'
// 논리합(||) 연산자
true || anything // true
false || anything // anything

// 논리곱(&&) 연산자
true && anything // anything
false && anything // false
  • 객체를 가리키기를 기대하는 변수가 null 또는 undefined가 아닌지 확인하고 프로퍼티를 참조할 때,

    Key Ponint 💡
    객체는 키(Key)값(value로 구성된 프로퍼티의 집합니다.


var elem = null
var value = elem.value // TypeError

var value = elem && elem.value // null

var elems = {key:1, value:'하하하'}
var value = elems && elems.value // '하하하'

7.2. 옵셔널 체이닝 연산자(?.)

Key Ponint 💡
좌항의 피연산자가 null 또는 undefined인 경우 undefined를 반환하고, 그렇지 않으면 우항의 프로퍼티를 참조를 참조한다.


var elem = null

// elem이 Falsy값이면 elem으로 평가되, Truthy 값이면 elem.value로 평가된다.
var value = elem?.value
console.log(value) // undefined

7.3. null 병합 연산자(??)

Key Ponint 💡
null 병합연산자(??)는 좌항의 피연산자가 null또는 undefined인 경우 우항의 피연산자를 반환하고, 그렇지 않으면 좌항의 피연산자를 반환하고, 그렇지 않으면 좌항의 피연산자를 반환한다.

*변수에 기본값을 설정할 때 유용하다.


// 0이나 ''도 기본값으로 유효하다면 유용하다.
var foo = null ?? 'default string';
console.log(foo); // 'default string'

// ?? 와 || 의 차이
// ??
var foo = '' ?? 'default string';
console.log(foo); // ''

// ||
var foo = '' || 'default string';
console.log(foo) // 'default string'


8. 객체 리터럴

  • 자바스크립트는 객체 기반의 프로그래밍 언어이다.
  • 원시값을 제외한 나머지 값(함수, 배열, 정규표현식 등_ 모두 객체이다.
  • 원시타입은 단 하나의 값만 나타내지만, 객체 타입은 다양한 타입의 값(원시 값 또는 다른 객체)을 하나의 단위로 구성한 복합적인 자료구조이다.
  • 원시 값은 변경 불가능한 값이지만, 객체 타입의 값은 변경이 가능한 값이다.

Key Ponint 💡
객체는 프로퍼티메서드의 집합체이다.

  • 프로퍼티 : 객체의 상태를 나타내는 값(data)
  • 메서드 : 프로퍼티(상태 데이터)를 참조하고 조작할 수 있는 동작(behavior)

*자바스크립트의 객체 지향 방법

  • 객체 리터럴
  • Object 생성자 함수
  • 생성자 함수
  • Object.create 메서드
  • 클래스

8.1. 프로퍼티

Key Ponint 💡
객체는 프로퍼티의 집합이며, 프로퍼티는 키와 값으로 구성된다.

const person = {
 // 프로퍼티 키는 name, 프로퍼티 값은 'Lee'
  name : 'Lee'
  
  // 프로퍼티 키는 age, 프로퍼티 값은 20
  age : 20
  
}
  • 프로퍼티 키 : 빈 문자열을 포함하는 모든 문자열 또는 심벌 값
  • 프로퍼티 값 : 자바스크립트에서 사용할 수 있는 모든 값

1) 프로퍼티 동적 생성

  • 존재하지 않느 ㄴ프로퍼티에 값을 할당하면 프로퍼티가 동적으로 생성되어 추가되고 프로퍼티 값이 할당된다.

var person = {
  name : 'Lee'
}
person.age = 20

console.log(person) // {name : 'Lee', age:20}

8.2. 메서드

Key Ponint 💡
메서드는 객체에 묶여 있는 함수를 의미한다.

9. 원시 값과 객체의 비교

Key Ponint 💡
자바스크립트의 타입은 원시타입과 객체타입으로 구분할 수 있다.

  • 원시 타입의 값 : 변경 불가능한 값
  • 객체 타입의 값 : 변경 가능한 값

Key Ponint 💡

  • 원시 타입의 값을 변수에 할당 : 변수(확보된 메모리 공간)에는 실제 값이 저장된다.
  • 객체 타입의 값을 변수에 할당 : 변수(확보된 메모리 공간)에는 참조 값이 저장된다.

Key Ponint 💡

  • 값에 의한 전달 : 원시 값을 갖는 변수를 다른 변수에 할당하면 원시 값이 복사되어 전달
  • 참조에 의한 전달 : 객체를 가리키는 변수를 다른 변수에 할당

9.1. 원시 값

Key Ponint 💡
원시타입의 값은 변경 불가능하므로, 한번 생성된 원시 값은 읽기 전용(Read only)값으로 변경할 수 없다.

1) 불변성

원시 값은 변경 불가능한 값이기 때문에, 값을 직접 변경할 수 없다. 따라서 변수 값을 변경하기 위해 원시 값을 재할당하면 새로운 메모리 공간을 확보하고 재할당한 값을 저장한 후, 변수가 참조하던 메모리 공간의 주소를 변경한다.
불변성을 갖는 원시 값을 할당한 변수는 재할당 이외에 변수 값을 변경할 수 있는 방법이 없다.

9.2. 객체

객체란? 💡

  • 객체(참조) 타입의 값, 즉 객체는 변경가능한 값이다.

객체는 프로퍼티의 개수가 정해져 있지 않으며, 동적으로 추가되고 삭제할 수 있다. 또한, 프로퍼티의 값에도 제약이 없다.

*자바스크립트가 객체의 관리 방식

  • 자바스크립트 엔진은 해시테이블과 유사하지만, 더나은 성능을 위해 일반적인 해시테이블보다 나은 방법으로 객체를 구한다.
  • 히든 클래스라는 방식을 사용해 객체의 프로퍼티에 접근하는 정도의 성능을 보장한다.

1) 변경 가능한 값

객체를 할당한 변수가 기억하는 메모리 주소를 통해 메모리 공간에 접근하면 참조 값에 접근할 수 있다.
참조 값은 생성도니 객체가 저장된 메모리 공간의 주소, 그 자체다.

2) 객체가 변경 가능한 값으로 설계된 이유

객체는 원시값처럼 크기가 일정하지 않아서, 복사해서 생성하는 비용이 많이든다. 즉, 메모리를 효율적으로 사용하기 어렵다. 따라서 객체는 객체를 복사해 생성하는 비용을 절약하기 위해서 변경 가능한 값으로 설계되었고, 이로인해 여러 개의 식별자가 하나의 객체를 공유한다는 구조적인 단점을 안고있다.

3) 참조에 의한 전달

참조에 의한 전달 💡

  • 객체를 가리키는 변수(원본, person)를 다른 변수(사본, copy)에 할당하면 원본의 참조 값이 복사되어 전달된다.
var person ={
	name : 'Lee'
}
// 얕은 복사 : 참조 값을 복사
var copy = person;
  • person을 사본 copy에 할당하면, 원본 person의 참조 갑을 복사해서 copy에 저장한다.
  • 원본 person과 사본 cpoy는 저장된 메모리 주소는 다르지만 동일한 참조 값을 갖는다.
  • 이것은 두 개의 식별자가 하나의 객체를 공유하는 것을 의미한다.
copy === person // true

// copy를 통해 객체를 변경한다.
copy.name = 'Kim'

// person을 통해 겍체를 변경한다. 
person.address = 'Seoul'

// copy와 person은 동일한 객체를 가리킨다.
// 따라서, 어느 한쪽에서 객체를 변경하면 서로 영향을 주고 받는다.
console.log(person) // {name: 'Kim', address: 'Seoul'}
console.log(copy) // {name: 'Kim', address: 'Seoul'}

값에 의한 전달 vs 참조에 의한 전달 💡

  • 값에 의한 전달참조에 의한 전달은 식별자가 기억하는 메모리 공간에 저장되어 있는 값을 복사해서 잔달하는 면에서는 동일하다.
  • 자바스크립트에서 참조에 의한 전달은 존재하지 않고 값에 의한 전달만이 존재한다고 말할 수 있다.

참조에 의한 전달의 부작용💡

  • 객체를 가리키는 변수를 다른 변수에 할당하면 원본의 참조값이 복사되어 전달되는데, 이때 두 객체는 저장된 메모리 주소는 다르지만 동일한 참조값을 갖는다.
  • 즉, 두 객체는 동일한 객체를 가리킨다. 따라서 원본 또는 사본 중 어느 한쪽에서 객체의 프로퍼티 값을 변경하거나 삭제하면 서로 영향을 주고 받는다.
// 얕은 복사
const person = {
	name : 'Lee'
}
const copy = {...person}

console.log(person===copy) // false
console.log(person.name === copy.name) // true

참조에 의한 전달 부작용 해결방법💡

  • 객체를 불변 객체로 만들어 사용한다. 객체의 복사본을 새롭게 생성하는 비용은 들지만, 객체를 마치 원시값처럼 변경 불가능한 값으로 동작하게 만드는 것이다.
  • 객체의 상태 변경이 필요한 경우에는 객체를 깊은 복사(Deep copy)를 통해 새로운 객체를 생성하고 재할당을 통해 교체한다.
  • 이를 통해 외부 상태가 변경되는 부수 효과를 없앨 수 있다.

9.3. 참고

유사 배열 객체💡

  • 마치 배열처럼 인덱스로 프로퍼티 값에 접근할 수 있고, length 프로퍼티를 갖는 객체를 말한다.
  • length 프로퍼티를 갖기 때문에 유사배열객체이고, for 문으로 순회할 수도 있다.

문자열💡

  • 자바스크립트의 문자열은 유사배열객체이면서 이터러블이므로 배열과 유사하게 각 문자에 접근할 수 있다.
profile
이게 마즐까?

0개의 댓글