개발 일기

변수 선언 ? 본문

컴퓨터 언어/Typescript

변수 선언 ?

이건욱

Typescript도 Javascript에 상위 집합이므로 당연히 var , let , const을 지원합니다.

 

기본적으로 var보다는 let , const을 선호하고 그 이유는 아래와 같이 스코프 규칙에 있습니다.

function f(shouldInitialize: boolean) {
    if (shouldInitialize) {
        var x = 10;
    }

    return x;
}

f(true);  // returns '10'
f(false); // returns 'undefined'

위와 같이 if문에서 x을 생성을 했지만 아래에서 x을 참조하고 있습니다.

var선언은 블록과 관계없이 이를 감싸고 있는 함수 , 모듈 , 네임스페이스 , 전역 스코프에서 접근 할수 있습니다.

 

더구나나 여러번 선언도 가능하기 때문에 실수를 유발할수가 있습니다.

 

[예시]

function sumMatrix(matrix: number[][]) {
    var sum = 0;
    for (var i = 0; i < matrix.length; i++) {
        var currentRow = matrix[i];
        for (var i = 0; i < currentRow.length; i++) {
            sum += currentRow[i];
        }
    }

    return sum;
}

let temp : number[][] = [[1 , 2 , 3 , 4 , 5], [ 5, 3, 1]]

console.log(sumMatrix(temp))
// LOG => 15

 

변수 캡쳐링의 단점

[예시]

같은 scope에 i를 참조하기 때문에 setTimeout은 ~초 후에 실행을 하겠지만 그 때 당시에 for문에 i는 항상 10이기 때문입니다.

for (var i = 0; i < 10; i++) {
    setTimeout(function() { console.log(i); }, 100 * i);
}

10
10
10
10
10
10
10
10
10
10

따라서 다음과 같이 적용해야합니다.

for (var i = 0; i < 10; i++) {
    // capture the current state of 'i'
    // by invoking a function with its current value
    (function(i) {
        setTimeout(function() { console.log(i); }, 100 * i);
    })(i);
}

그래서 이제 var의 문제점을 고친 let을 살펴보도록 하겠습니다.

 

let은 이를 가장 가깝게 싸고있는 블록 혹은 for loop밖에서도 접근을 할수가 없습니다.

[예시]

function f(input: boolean) {
    let a = 100;

    if (input) {
        // Still okay to reference 'a'
        let b = a + 1;
        return b;
    }

    // Error: 'b' doesn't exist here
    return b;
}
function foo() {
    // okay to capture 'a'
    return a;
}

// illegal call 'foo' before 'a' is declared
// runtimes should throw an error here
foo();

let a;

 

var는 재선언이 다음과 가능하다고 했습니다.

function f(x) {
    var x;
    var x;

    if (true) {
        var x;
    }
}

 

하지만 let은 재선언이 불가능합니다.

let x = 10;
let x = 20; // error: can't re-declare 'x' in the same scope
function f(x) {
    let x = 100; // error: interferes with parameter declaration
}

function g() {
    let x = 100;
    var x = 100; // error: can't have both declarations of 'x'
}

 

let을 사용하게 되면 다음과 같은 코드도 정상적으로 작동을합니다.

function sumMatrix(matrix: number[][]) {
    let sum = 0;
    for (let i = 0; i < matrix.length; i++) {
        var currentRow = matrix[i];
        for (let i = 0; i < currentRow.length; i++) {
            sum += currentRow[i];
        }
    }

    return sum;
}

 

const는 let과 같은 스코프를 가지고 있지만 재할당을 할수가 없습니다.

[예시]

const numLivesForCat = 9;
const kitty = {
    name: "Aurora",
    numLives: numLivesForCat,
}

// Error
kitty = {
    name: "Danielle",
    numLives: numLivesForCat
};

// all "okay"
kitty.name = "Rory";
kitty.name = "Kitty";
kitty.name = "Cat";
kitty.numLives--;

 

배열 구조 분해 :)

let input = [1, 2];
let [first, second] = input;
console.log(first); // outputs 1
console.log(second); // outputs 2

// 다른 방법 접근
first = input[0];
second = input[1];

// swap variables
[first, second] = [second, first];

// 함수에도 적용 가능
function f([first, second]: [number, number]) {
    console.log(first);
    console.log(second);
}
f([1, 2]);

let [first, ...rest] = [1, 2, 3, 4];
console.log(first); // outputs 1
console.log(rest); // outputs [ 2, 3, 4 ]

// 나머지 무시 합니다.
let [first] = [1, 2, 3, 4];
console.log(first); // outputs 1

let [, second, , fourth] = [1, 2, 3, 4];
console.log(second); // outputs 2
console.log(fourth); // outputs 4

 

'컴퓨터 언어 > Typescript' 카테고리의 다른 글

Literal Types ?  (0) 2020.05.03
Function ?  (0) 2020.05.03
Class ?  (0) 2020.05.01
Interface ?  (0) 2020.04.30
기본 Type ?  (0) 2020.04.18
Comments