-
JS (ES6 & above) - Variable type, Scope, Hoisting자바스크립트 Study/자바스크립트 2021. 3. 28. 15:38
참조 :
velog.io/@marcus/2019-02-10-1702-%EC%9E%91%EC%84%B1%EB%90%A8
www.youtube.com/watch?v=OCCpGh4ujb8&list=PLv2d7VI9OotTVOL4QmPfvJWPJvkmv6h-2&index=3
medium.com/@_diana_lee/javascript-hoisting-%ED%98%B8%EC%9D%B4%EC%8A%A4%ED%8C%85-2df9955db5c7
■ let, var, const ( 변수 선언 방식 )
> ES6 에서 추가된 변수
1) let
1회 할당 가능, 재할당 불가, mutable
2) const
1회 할당 가능, 재할당 불가, immutable
> variable을 가르키는 pointer에 lock 걸려있음
> 장점 :
- Security // hacker 등의 변수 조정 방지
- Thread Safety
- Human mistakes
를 줄일 수 있음
3) var
유동적 할당 가능 : 요즘 거의 안씀
// let let testCase = 'let' // output: let let testCase = 'let2' // output: Uncaught SyntaxError: Identifier 'testCase' has already been declared testCase = 'let3' // output: let3 // const const testCase = 'const' // output: const const testCase = 'const2' // output: Uncaught SyntaxError: Identifier 'testCase' has already been declared testCase = 'const3' // output: Uncaught TypeError:Assignment to constant variable.
■ 변수 타입
(1) primitive
single item : number, string, boolean, null, undefined, symbol
(2) object : box container
(3) function : first-class function
▶ mutable / immutable
Immutable type :
primitive types, frozen objects(eg. object.freeze( )),... string(메모리에 한번에 올리고 변경시 전체가 변경)
→ Favored for reason
- security
- thread safty
- reduced human errors
Mutable type :
all objects by default are mutable in JS
1) fisrt-class function
정의 : 함수도 객체로 취급, 변수에 할당, parameter로 전달, return 값으로 돌려주는 등의 변수 취급 가능
2) number - 세부 사항
infinity, -infinity, NaN
- infinity : 양의 number 타입을 0으로 나눔
- -infinity : 음의 number 타입을 0으로 나눔
- NaN : 숫자가 아닌 것을 number와 연산을 했을 경우
3) string - 세부 사항
- + 연산으로 concat 가능
- 1글자 , 그 이상의 글자 길이도 같은 string 타입
- template literal로 console 기능 쉽게 사용
const brendan = 'brendan'; console.log(`value : ${greeting}, type : ${typeof greeting}`) ; // backtick 사용
4) boolean - 세부사항
- True 판단 : any ^( for all false )
- False 판단 : 0, null, undefined, NaN, '' // empty string
- expression의 evaluation
5) null / undefined - 세부사항
- null : 명시적으로 null을 할당하여 선언→초기화→할당 까지 통과했음을 알려줄 수 있음
- undefined : var / let / const 모두 초기화 까지 통과한 경우 undefined 자동 할당 되어있음
6) Symbol - 세부사항
> unique한 object를 만들 때 사용
> 예시로 같은 string이더라도 다른 string으로 인식이 될 수 있음
const gSymbol1 = Symbol('id'); const gSymbol2 = Symbol('id'); console.log(gSymbol1 === gSymbol2); >>> false const symbol1 = Symbol.for('id'); const sumbol2 - Symbol.for('id'); console.log(symbol1 === symbol2); >>> true // console로 symbol 출력은 항상 description 프로퍼티로 stringfy 된 값을 가져와야함 cosole.log(`value : ${symbol1.description}, type : ${typeof symbol1}`);
7) Object - 세부사항
> const로 생성해도 property는 변경 가능
> const 가리키는 포인터의 변수 자체만 lock 되어있고,
그 변수의 프로퍼티가 가르키는 포인터는 lock이 안되어있기 때문
> 메모리 할당이 매우 크기 때문에,
다음과 같이 reference들로 구성
(a) 객체 리터럴로 생성
var emptyObject = {}; console.log(typeof emptyObject); // object var person = { name: 'Lee', gender: 'male', sayHello: function () { console.log('Hi! My name is ' + this.name); } }; console.log(typeof person); >>> object console.log(person); >>> {name: "Lee", gender: "male", sayHello: ƒ} person.sayHello(); >>> Hi! My name is Lee
(b) Object 생성자 함수로 생성
> 리털로 생성과 동일, 리터럴에서는 자동으로 object함수 call하여 생성
// 빈 객체의 생성 var person = new Object(); // 프로퍼티 추가 person.name = 'Lee'; person.gender = 'male'; person.sayHello = function () { console.log('Hi! My name is ' + this.name); }; console.log(typeof person); // object console.log(person); // {name: "Lee", gender: "male", sayHello: ƒ} person.sayHello(); // Hi! My name is Lee
★ 객체 / 프로퍼티 추가 참조
> 나중에 한번 읽어보기
8) Dynamic typing
(a) 정의 :
Static하게 type이 필요한 언어 기준 or Class 등을 쓰는 언어와 다르게
→ JS는 할당하는 값에 따라서 type이 변화... 그래서 type script 존재
■ Scope
1) 정의
global scope, local scope 두가지
> global scope는 파일의 최상단 scope에 변수 설정하면 됨
2) 종류
(a) Function scope
function marcusHello () { const hello = 'Hello Marcus!' console.log(hello) } marcusHello() // 'Hello Marcus!!' console.log(hello) // Error, hello is not defined
(b) Block scope
{ let name = 'HJ"; console.log(name); // HJ 출력 } console.log(name); // scope가 global로 설정 되어있지 않아서 아무것도 출력 안됨
■ Hoising
1) 정의 :
변수 / 함수의 정의가 그 Scope에 따라
" 선언 / 초기화 / 할당 " 이 분리되는 것을 의미
> hoising 대상이 함수 / block 내에서 정의되면 선언이 함수 / block 컨텍스트의 최상위로 변경
오로지 선언만 끌어올려지고, 할당은 해당사항 없음
> global 밑에 선언된 함수는 선언이 위로 hoisting 됨 (python도 마찬가지 - 생성자 거치기 전을 제외하고)
2) 변수의 생성과정
(a) 3단계 설명
- 선언단계 : 변수 객체( Variable Object )에 변수를 등록
- 초기화단계 : 변수 객체에 등록된 변수에 메모리를 할당, undefined로 초기화
- 할당단계 : undefined로 초기화 된 변수에 값을 할당
3) 예시
(a) Var의 hoising
> 1.선언단계, 2.초기화 단계 가 동시에 수행
// 스코프의 최상단에서 선언단계와 초기화단계가 실행된다. console.log(foo); >>> undefined var foo; // -------------> 이부분이 scope의 최상단으로 옮겨진다. foo = "test"; // 할당단계 console.log(foo); >>> test
> 그 어느 시점의 Scope에 있던지 globalScope으로 hoising 되어서 "위험한" 선언방식, 초창기 빠른 개발 때문에 사용되었음
> 지금은 거의 안쓴다
(b) Let / Const 의 hoisting
> 1.선언단계 수행 이후, 2.초기화 단계 는 실제 코드의 선언부를 읽을 때 실행되어 TDZ 발생
> 1 ~ 2단계 사이 어딘가에서 변수 접근시 undefined로 초기화 되지 않았으므로 Reference error 발생
// 스코프의 선두에서 선언 단계가 실행 // 아직 변수가 초기화(메모리 공간 확보와 undefined로 초기화)되지 않음 // 따라서 변수 선언문 이전에 변수를 참조할 수 없음 console.log(foo); >>> ReferenceError: foo is not defined let foo; // 변수 선언문에서 초기화 단계가 실행 console.log(foo); >>> undefined foo = 1; // 할당문에서 할당 단계가 실행된다. console.log(foo); >>> 1
■ 최상단에서 같은 이름의 변수가 있을 때
let foo = 1; { // 스코프의 선두에서 지역변수의 선언 단계가 실행된다. // 하지만 초기화 단계는 이루어지지 않았다. console.log(foo); // ReferenceError: foo is not defined // 초기화 및 할당 단계 let foo = 2; // ---------> hoisting 되어 scope 최상단으로 옮겨짐 // 블록 바깥의 foo / 안쪽의 foo는 다른 Var object여서 // let임에도 재할당 되는 것 처럼 보임 // 실제로는 다른 변수 console.log(foo); >>> 2 출력! } console.log(foo); >>> 다시 1 출력!
반응형'자바스크립트 Study > 자바스크립트' 카테고리의 다른 글
JS (ES6 & above) - Functions (0) 2021.04.13 JS (ES6 & above) - Operators (0) 2021.04.13 Html에 JS의 위치 / JS 파일 선언의 기본 (0) 2021.03.27 자바스크립트 공식 사이트(html, css포함) (0) 2021.03.27 Vscode / node.js npm (0) 2021.03.27