프로그래밍

자바 스크립트 변수에 관해서

Jay Tech 2017. 2. 2. 23:56
반응형

자바스크립트의 변수들은 기본적으로 모든 형태를 수용할 수 있도록 형에 대한 제약이 없다. 자바스크립트에서 객체가 아닌 기본적인 키워드와 문자로 활용되는 기본형은 다음과 같다.


number(숫자)

string(문자열)

boolean(이진값)

undefined

null

symbol


typeof 연산자로 형을 검사할 수 있다. 예를들어


typeof 1; // "number" 출력됨


신기한 점은 null을 타입검사를 하면 object가 나온다. 그 이유는 null이면 0값을 가지는 객체로 취급하도록 설계되었기 때문이다. 이말인 즉슨 타입검사 코드를 삽입할 때 null검사까지 해줘야 한다는 것이다.  예시를 보자.


if(variable !== null && typeof variable === "object" ) {

// ... 

}


이런 식으로 null을 걸러줘야 한다는 것이다. typeof variable === "object"라고만 조건을 써주면 null이 같이 흘러가기 때문이다.


cf) == 와 === 의 차이

==는 Equal Operator 이고 ===는 Strict Equal Operator 이다.

==는 값을 비교하고 ===는 값과 형까지 비교한다. 예를들어 1과 "1"은 ==로 비교하면 true이지만 ===로 비교하면 false이다.



헷갈리는 instanceof 연산자에 대해


true instanceof Boolean    // false

true는 기본형이라서 boolean객체의 instanceof가 false로 나타난다.


var color1 = new String("red");

var color2 = "red";


color1==color1    // true

color1 instanceof String    // true

color2 instanceof String    // false  ???

color2 instanceof Object    // false


color1.constructor === String     // true

color2.constructor === String     // true  ?????


color2의 생성자가 string인 이유는 연산할 때 내부적으로 형번환이 일어난 다음에 constructor에 접근하기 때문이다.


자 그렇다면


var color1 = new String("red");

var color2 = "red";

var color3 = String("red"); 

의 차이점을 살펴보자.


생성자로 호출한 것이라면 (new연산으로) String객체를 생성하여 반환한다. 즉 instanceof의 결과는 String이다. 나머지둘은 생성자로 호출되는 방식이 아니다. 그러므로 color2 === color3는 true값을 가진다. 즉 입력인자가 string이면 인자 그대로 반환하게 되어있다. 이것이 표준이다.


또한 기본형과 객체의 차이점은 속성부여 여부이다.


new String으로 만든 객체는 속성을 부여할 수 있다. 예를들어


var myVar = new String("hello");

myVar.number = "3"; 


이런식으로 속성을 부여하지만


var myVar2 = "hello";

myVar2.number = "2";    => 이런식으로 기본형으로 만들어 놓은 것에 속성을 부여할 수 없다.


기본형은 속성을 쓰지 못할까? 


그렇지 않다. String.prototype.trim 처럼 프로토타입을 정의하면 기본형으로 선언해도 이 속성을 사용할 수 있다.



글로벌 변수에 대해


글로벌 변수는 자제해야 한다. 웹의 특성상 고려해야할 것이 있기 때문이다.


1) 라이브러리 사용이나 여러 사람들이 작업한 파일들을 합칠때의 충돌


변수를 보호하기 위해 클로저를 사용할 수 있다. 이벤트를 위해 사용되는 변수들을 클로저 안에 선언함으로써 다른 소스와의 충돌을 피할 수 있다. div나 img같은 간단한 변수명은 쉽게 다른 소스와 충돌 할 수 있으므로 이렇게 보호하는 것이 좋다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
<html>
<body>
    <div id="wrapper">
        <button data-cb="1">Add div</button>
        <button data-cb="2">Add img</button>
        <button data-cb="delete">Clear</button>
        Adding below...<br/>
        <div id="appendDiv"></div>
    </div>
 
    <script>
    (function () {
        var appendDiv = document.getElementById("appendDiv");
            callback = { 
                "1": (function () {
                    var div = document.createElement("div");
 
                    div.innerHTML = "#1";
                    return function () {
                        return div.cloneNode(true);
                    }
                }()), 
                "2": (function () {
                    var img = document.createElement("img");
 
                    img.src="https://t1.daumcdn.net/cfile/tistory/203E5A424F471E3025";
                    return function () {
                        return img.cloneNode(true);
                    }
                }()),
                "delete":function () {
                    appendDiv.innerHTML = "";
                    return document.createTextNode("Cleared");
                }
            };
 
 
        function append(e) {
            var target = e.target || e.srcElement || event.srcElement,
                callbackFunction = callback[target.getAttribute("data-cb")];
 
            appendDiv.appendChild(callbackFunction());
        };
 
        document.getElementById("wrapper").addEventListener("click", append);
 
    }());
    </script>
</body>
</html>
 
//출처 : https://github.com/unikys/javascript_in_depth
 
cs



2) 비동기 처리에서 발생할 수 있는 문제


xhr변수를 함수 밖에 선언하여 여러번 클릭했을 때 매번 생성하는 리소스를 아낄 수 있다. 하지만 응답이 돌아오지 않았는데 한번 더 누른다던지하는 상황이 오면 생각치 않은 문제가 발생할 수 있다. ajax를 활용할 때는 글로벌 변수를 매우 주의해야 한다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<html>
<body>
    <button id="buttonCheckId">Click</button>
    <script>
 
    var xhr = new XMLHttpRequest();
    document.getElementById("buttonCheckId").addEventListener("click"function () {
        var id = document.getElementById("inputId").value;
        xhr.open("GET""http://unikys.tistory.com/api/checkId?id=" + id);
        xhr.onreadystatechange = function () {
            if (xhr.readyStatus === 4 && xhr.status === 200) {
                if (xhr.responseText === "1") {
                    alert("ID exists!");
                }
            }
        };
    });
 
    </script>
</body>
</html>
 
cs



3) 자원의 관점


자바스크립트는 변수의 메모리 관리 전략으로 자바의 가비지 컬렉션을 사용하고 있어서 변수를 참조하고 있는 다른 무언가가 있다면 해제하지 않는다. 더욱이 자바스크립트는 이벤트 콜백 함수가 많기 때문에 웬만한 글로벌 변수는 하나 이상의 함수에서 참조하고 있을 가능성이 높다. 모바일에서는 더욱 리소스에 대한 압박이 커질 것이다.

그래서 잠시 사용하는 변수같은 경우에는 글로벌 변수가 아닌 로컬 변수로 현재의 스코프에 올려서 사용하고 사용하지 않을 때는 해제하는 것이 좋다. 또한 ajax로 대용량 문자열을 받을 때는 오래 가지고 있을 수록 메모리에 영향을 미치게 되므로 로컬로 보관하고 바로 메모리를 해재해주는것이 좋다.



이런 특징 말고도 더 많지만 대표적인 특징만 보았다. 글로벌 변수는 조심해야 할 부분임에 틀림없다.

반응형