느슨한 타입(loosely typed)의 동적(dynamic)언어
느슨한 타입 : 타입없이 변수를 선언
강력한 타입 언어: 타입과 함께 변수를 선언
동적언어:
js타입
js 형변환
- 함수와 연산자에 전달되는 값은 대부분 적절한 자료형으로 자동 변환
- 문자형으로 변환 : String(value)
- 숫자형으로 변환 : 숫자형이 아닌 값에 수학과 관련된 표현식,함수에서 자동으로 변환 (나누기, 곱하기), Number(value)
- 불린형으로 변환 : 논리 연산시 발생
( "0", "(공백)"시에 불린형 변환시 true)
==, ===
느슨한 타입의 동적 언어의 문제점과 보완 방법
undefined와 null의 차이
undefined : 값이 할당되지 않은 상태
null : 존재하지 않는, 비어있는, 알 수 없는 값
차이 : undefined는 변수를 선언만 하더라도 할당되지만 null은 변수를 선언한 수에 null로 값을 바꿈
(출처:https://webclub.tistory.com/1)
기본형 데이터와 참조형 데이터
- 기본형 타입(primitive data type)은 변경 불가능한 값(immutable value)
=> 직접 변경 불가능(메모리 영역 변경 불가능), 재할당 가능
- 원시 타입외 모든 값은 객체(Object) 타입이며 객체 타입은 변경 가능한 값(mutable value)
=> 새로운 값 만들 필요없이 직접 변경 가능
불변 객체를 만드는 방법
의도하지 않은 객체의 변경이 발생하는 원인의 대다수는 “레퍼런스를 참조한 다른 객체에서 객체를 변경”하기 때문
객체를 불변객체로 만들어 프로퍼티의 변경을 방지하며 객체의 변경이 필요한 경우에는 참조가 아닌 객체의 방어적 복사(defensive copy)를 통해 새로운 객체를 생성한 후 변경
객체의 방어적 복사(Object.assign)
- Object.assign은 타킷 객체로 소스 객체의 프로퍼티를 복사한다. 이때 소스 객체의 프로퍼티와 동일한 프로퍼티를 가진 타켓 객체의 프로퍼티들은 소스 객체의 프로퍼티로 덮어쓰기된다. 리턴값으로 타킷 객체를 반환한다. ES6에서 추가된 메소드이며 Internet Explorer는 지원하지 않는다.
불변객체화를 통한 객체 변경 방지(Object.freeze)
Object.freeze()를 사용하여 불변(immutable) 객체, 하지만 객체 내부의 객체(Nested Object)는 변경가능하다.
내부 객체까지 변경 불가능하게 만들려면 Deep freeze를 하여야 한다.
얕은 복사와 깊은 복사
- 얕은 복사 :
참조값을 복사할 때는 변수가 객체의 참조를 가리키고 있기 때문에 복사된 변수 또한 객체가 저장된 메모리 공간의 참조를 가리키고 있음. 그래서 복사를 하고 객체를 수정하면 두 변수는 똑같은 참조를 가리키고 있기 때문에 기존 객체를 저장한 변수에 영향을 끼침. 이처럼 객체의 참조값(주소값)을 복사하는 것
- Object.assign()
- 전개연산자
- 깊은 복사 :
원시값을 복사할 때 그 값은 또 다른 독립적인 메모리 공간에 할당하기 때문에, 복사를 하고 값을 수정해도 기존 원시값을 저장한 변수에는 영향을 끼치지 않음. 이처럼 실제 값을 복사하는 것!
- 다른말로 하면 깊은 복사된 객체는 객체안에 객체가 있을 경우에도 원본과의 참조가 완전히 끊어진 객체를 말한다.
- {...arr} 새로운 객체에 arr값들을 채우는 것
- 재귀함수를 이용한 복사
- JSON.stringify()
- 라이브러리 사용( lodash 라이브러리 사용)
let, const, var, function
let : let 키워드로는 변수 중복 선언이 불가하지만, 재할당은 가능
const : 재선언 불가, 재할당 불가, 객체는 가능(불변을 의미하지는 않음)
- let과 다른점이 있다면, 반드시 선언과 초기화를 동시에 진행
var : var 키워드를 이용한 변수 선언은 선언 단계와 초기화 단계가 동시에 진행,
- 호이스팅 발생
- 중복 선언 발생
-함수 레벨 스코프
function: 유사한 동작을 하는 코드가 여러 곳에서 필요할 때
콘솔에 찍힐 b 값을 예상해보고, 어디에서 선언된 “b”가 몇번째 라인에서 호출한 console.log에 찍혔는지, 왜 그런지 설명해보세요.
주석을 풀어보고 오류가 난다면 왜 오류가 나는 지 설명하고 오류를 수정해보세요.
console.log(a)는 블록 레벨 스코프이기에 찾지 못함
전역 변수 b 는 1이기에 첫번째 출력값 1,
hi()의 값은 const a=1, let b=100+1을 받기에 1,101 (블록레벨스코프이기에 지역변수로 적용)
세번째 콘솔은 전역 변수 b를 받기에 1
블록 레벨 스코프(Block-level scope)
모든 코드 블록(함수, if 문, for 문, while 문, try/catch 문 등) 내에서 선언된 변수는 코드 블록 내에서만 유효하며 코드 블록 외부에서는 참조할 수 없다. 즉, 코드 블록 내부에서 선언한 변수는 지역 변수이다.