이 글은 자바스크립트 개론을 읽고 개인적으로 정리한 내용입니다.


자바스크립트 기초: 값, 변수, 제어 흐름

값의 타입 6가지

  • 숫자, 불리언, 문자열, 객체, 함수, undefined

숫자

  • 자바스크립트는 숫자를 내부적으로 64비트 부동소수점 값으로 표현한다. 다른 언어처럼 정수를 위한 특별한 자료형이 없다. 즉, 정수(Integer)든 소수(Decimal)든 간에 부동 소수점 방식으로 표현되는 것이다.

  • 정수(Integer)도 부동 소수점으로 표현된다는 것은 수의 정확도가 제한됨을 의미한다. 단, 52개의 비트로 표현될 수 있는 정수는 항상 정확하게 계산된다.

  • 하지만 소수(Decimal)의 경우에는 항상 값이 근사치임을 알고 있어야 한다.

문자열

  • 문자열 안에서 이스케이프 기호 \를 사용하면, \ 다음에 오는 문자는 특별한 의미가 있음을 알릴 수 있다. 주로 따옴표' 혹은 쌍따옴표("), 줄바꿈, 탭을 문자열 안에서 표현할 때 사용된다.

  • 문자열을 대상으로 비교 연산자(>, <, >=, <=, ==)를 사용하면 유니코드를 기준으로 비교 대상의 문자열의 왼쪽 문자부터 비교한다.

표현식(expression)과 문장(statement)

  • 값을 생성하는 코드조각을 표현식(expression)이라 한다.
  • 화면에 문자가 출력되거나, 변수에 저장된 값을 변경하는 것처럼 프로그램 상에서 부수효과(side effect)를 일으키는 코드 조각을 문(statement)이라 한다.

환경(environment)

  • 특정 시점에 존재하는 변수의 값, 변수의 모음이 있는 공간을 환경이라 한다.
  • 프로그램이 구동되면 개발자가 선언한 변수 외에도 브라우저의 표준 변수가 환경에 담긴다.
  • 환경은 다른 페이지로 이동할때까지 유지된다.

함수

  • 함수는 표준 환경에서 제공되는 값이다.
  • 함수는 코드 조각을 담을 수 있으며, 함수값(함수명)은 그런 코드 조각을 가르킨다.
  • 함수에 담긴 코드를 실행하는 것은 호출(invoke)하거나 적용(apply)한다고 한다.
  • 함수를 호출할 때는 값을 넘겨줄 수 있다.
    호출하는 쪽에서 넘기는 값들은 인자(argument)라고 한다.
    선언하는 쪽에서 받는 값들은 매개변수(parameter)라고 한다.

반복문

  • 반복문의 종류에는 while, for, do while이 있다.
  • while, for는 조건이 만족되지 않으면 반복문의 내용이 한 번도 실행되지 않는다.
  • do while은 조건이 만족되든 안되든 반복문의 내용을 무조건 1번은 실행한다.

undefined

  • 값이 할당되지 않는 변수는 undefined라는 특별한 값을 얻는다.
  • 코드 상에서 값을 반환하지 않는 함수도 undefined반환한다.
  • 비슷한 값으로 null이 있는데, null은 값이 정의되었지만 아직 값이 없음을 알린다.
  • 참고로 undefined == null은 true를 반환한다.

형변환

  • 자바스크립트에서 연산자의 피연산자는 자동 형변환이 일어날 수 있다. 두 값중 다른 값의 타입으로 변환이 된다.
  • 조건문, 반복문의 조건식의 값이 불리언이 아니면 자동으로 불리언으로 형변환된다.
  • 문자열을 대상으로 ‘+’가 아닌 산술 연산자가 사용되면 문자열은 숫자로 형변환된다. 이 때, 숫자가 될 수 없는 문자열을 NaN이 된다. 문자열이 숫자가 될 수 없는지 판단하기 위해 NaN와 직접 비교하는 것은 정확하지 않다. 변수에 NaN가 있는지 판단할 때는 isNaN 함수를 사용하자.

&& 와 ||

  • AND(&&)와 OR(||) 연산자는 불리언 값을 반환하지 않고, 정확히 말하면 피연산자를 반환한다.
  • OR(||)은 왼쪽의 값을 보고, 그 값이 불리언으로 변환됐을 때 false이면 오른쪽의 값을 살핀다. 만약 왼쪽의 값이 true이면 오른쪽 값을 살피지 않고 왼쪽의 값을 반환한다. 
  • AND(&&)는 왼쪽의 값을 보고, 그 값이 불리언으로 변환했을 때 true이면 오른쪽의 값을 살핀다. 만약 왼쪽의 값이 false이면 오른쪽 값을 살피지 않고 false를 반환한다

기타

  • 문자열을 정수로 변환할 때는 Number 객체를 사용한다. parseInt는 문자열을 해석(parse)할 때 사용한다.
  • 여기서 말하는 window.isNaN은 부정확하다. 대신에 NaN를 비교할 때는 ES6에서 포함된 Number.isNaN를 사용하면 된다.


 프론트 개발을 하면서 웹 상에 돌아다니는 코드를 보면 배열의 마지막에 쉼표를 찍는 경우를 종종 봤었는데 왜 이걸 쓰는지 이유는 모르고 그냥 넘어갔던 것 같다. 의외로 큰 뜻이 있으면 어떡하나 싶어서 찾아봤는데, 그다지 중요한 문제는 아닌 것 같다... 이 글은 MDN에 있는 Trailing Commas를 번역한 자료이다.


Trailing commas

Trailing comma(후행 쉼표)는 새로운 배열 요소, 파라메터, 프로퍼티를 자바스크립트 코드에 추가할 때 유용하다. 만약 새 프로퍼티를 더하고 싶고, 마지막 줄에 쉼표가 있다면 이전의 마지막 줄을 수정하지 않고 새로운 라인을 간단하게 추가할 수 있다. 이것은 버전관리 도구에서의 비교를 명확하게 하고, 코드 편집을 덜 귀찮게 할 것이다.

자바스크립트는 태어날 때부터 리터럴의 후행 쉼표를 허용해줬다. 그리고 ECMAScript 5에서는 객체 리터럴, ECMAScript 2017에서는 함수 파라메터에 후행 쉼표를 추가하는 것이 허용됐다.

그러나 JSON은 후행 쉼표를 허용하지 않는다.



배열, 객체 리터럴의 후행 쉼표

배열

자바스크립트는 배열의 후행 쉼표를 무시한다.

var arr = [
    1,
    2,
    3,
];

arr; // [1, 2, 3]
arr.length; // 3

만약 후행 쉼표가 한 개이상 사용되면 배열에 구멍이 생긴다. 구멍이 있는 배열은 희소(sparse) 하다고 불린다. 조밀한(dense) 배열은 구멍이 없다. Array.prototype.forEach( ) 혹은 Array.prototype.map( )으로 배열을 순회할 때는 배열의 구멍을 건너뛴다.

객체

ECMAScript 5부터는 객체 리터럴에도 후행 쉼표가 유효하다.

var object = {
    foo: "bar",
    baz: "qwerty",
    age: 42,
}; 


함수의 후행 쉼표

ECMAScript 2017은 함수 파라메터 목록에 후행 쉼표를 허용한다.

파라메터 정의

다음의 함수 정의 쌍들은 유효하며 서로 같은 의미다. 후행 쉼표는 함수 정의의 length 프로퍼티 혹은 arguments 객체에 영향을 주지 않는다.

function f(p) {}
function f(p, ) {}

(p) => {};
(p, ) => {};

후행 쉼표는 클래스나 객체의 메서드 정의에도 동작한다.

class C {
    one(a,) {},
    two(a, b,) {},
}

var obj = {
    one(a,) {},
    two(a, b,) {},
};

함수 호출

다음의 함수 호출 쌍들은 유효하며 서로 같은 의미다.

f(p);
f(p, );

Math.max(10, 20);
Math.max(10, 20,);

유효하지 않은 후행 쉼표

함수 파라메터 정의나 함수 호출이 쉼표만을 포함한다면 SyntaxError가 발생한다. 그리고 나머지 매개변수(rest parameter)를 사용할 때 마지막 쉼표는 허용되지 않는다.

function f(,) {} // SyntaxError: missing formal parameter
(,) => {};       // SyntaxError: expected expression, got ','
f(,)             // SyntaxError: expected expression, got ','

function f(...p,) {} // SyntaxError: parameter after rest parameter
(...p,) => {}        // SyntaxError: expected closing parenthesis, got ','


비구조화(destructuring)에서 후행 쉼표

비구조화 할당을 사용할 때는 후행 쉼표가 왼편에서만 허용된다.

// 후행 쉼표로 배열 비구조화
[a, b,] = [1, 2];

// 후행 쉼표로 객체 비구조화
var o = {
    p: 42,
    q: true,
};

var {p, q,} = o;

나머지 요소(rest element)를 사용할 때는 SyntaxError가 발생한다.

var [a, ...b,] = [1, 2, 3];
// SyntaxError: rest element may not have a trailing comma


JSON에서 후행 쉼표

객체의 후행 쉼표는 ECMAScript 5에서 소개됐다. JSON은 ES5 이전의 자바스크립트 문법을 기반으로 하기 때문에, JSON에서는 후행 쉼표가 허용되지 않는다.

두 라인은 모두 SyntaxError가 발생한다.

JSON.parse('[1, 2, 3, 4, ]');
JSON.parse('{"foo" : 1, }');
// SyntaxError JSON.parse: unexpected character
// at line 1 column 14 of the JSON data

JSON을 정확하게 파싱하기 위해 후행 쉼표를 생략해라.

JSON.parse('[1, 2, 3, 4 ]');
JSON.parse('{"foo" : 1 }');


'JavaScript' 카테고리의 다른 글

[JavaScript] 변수 스코프  (0) 2017.04.13
[JavaScript] 생성자 함수  (0) 2017.02.27
[JavaScript] 배열 연결  (0) 2017.01.26
[JavaScript] 동등, 일치 연산자  (0) 2016.10.04

이 글은 EcmaScript5를 기준으로 작성되었습니다.

JavaScript 스코프

변수 스코프?

변수 스코프란, 변수가 선언된 지점을 기준으로 변수에 접근할 수 있는 범위를 말하며, 다른 말로 유효범위라고도 한다. 다른 언어에서는 블록({})을 기준으로 변수 스코프가 형성되는 경우가 있지만, 자바스크립트는 아니다.

if(true) {
    var aa = 1;
}

console.log(aa);

실행결과

> 1

블록 안에서 선언된 변수 aa를 블록 밖에서도 접근이 가능하다.

스코프의 종류

자바스크립트에서 형성될 수 있는 스코프는 두 가지이다.

1. 함수 스코프

말 그대로 함수를 기준으로 스코프가 형성되는 것을 말한다. 함수 내부에서 선언된 변수는 외부에서 접근할 수 없다.

function myFunc() {
    var aa = 1;
}

console.log(aa); // Error!!

반대로 외부의 변수는 내부 함수에서 접근할 수 있다.

var aa = 1;

function myFunc() {
    console.log(aa);
}

myFunc(); // 1

2. 전역 스코프

전역 스코프(global scope)는 함수 밖의 영역을 말한다. 전역 스코프의 변수는 모든 함수 스코프에서 참조할 수 있다.

/* global scope */
var aa = 1;

function myFunc() {
    /* function scope */
    console.log(aa);
}

function anotherFunc() {
    /* function scope */
    console.log(aa);
}

myFunc();
anotherFunc();

실행결과

> 1
> 1

전역 스코프에 선언된 변수는 다른 자바스크립트 파일에서도 접근할 수 있다.

/* index.html */
/*
    <html>
    <head>
        <script src='myModule.js'></script>
        <script src='script.js'></script>
    </head>
    </html>
*/

/* myModule.js */
var a = 1;
console.log(b);

/* script.js */
var b = 2;
console.log(a);

실행결과

> Error! b is not defined
> 1

<script> 태그로 로딩되는 순서에 따라서 파일 사이에 전역 스코프의 접근이 가능해진다. 전역 스코프에 변수를 선언하게 되면 자바스크립트 파일간 영향을 미칠 수 있기 때문에(특히 써드파티 모듈을 사용하는 경우), 신중하게 다뤄야 한다.

호이스팅(Hoisting)

호이스팅(Hoisting, 끌어올림)이란 변수 선언문이 끌어올려지는 현상을 말한다.

/* 호이스팅이 일어나기 전 */
console.log(aa);
if(true) {
    var aa = 1;
}
console.log(aa);

function myFunc() {
    console.log(bb);
    var bb = 2;
    console.log(bb);
}

myFunc();

위의 코드는 변수 호이스팅에 의해 자바스크립트 엔진에서 이렇게 해석된다.

/* 호이스팅이 일어난 후 */
var aa;
console.log(aa);
if(true) {
    aa = 1;
}
console.log(aa);

function myFunc() {
    var bb;
    console.log(bb);
    bb = 2;
    console.log(bb);
}

myFunc();

실행 결과

> undefined
> 1
> undefined
> 2

전역 스코프에 있는 변수의 선언문은 자신이 속한 자바스크립트 파일의 최상단으로, 함수 스코프에 있는 변수의 선언문은 함수 스코프의 최상단으로 끌어올려진다.

주의해야 할 점은 선언문만 끌어올려지고, 할당문은 그대로 있는 것이다. 때문에 첫 번째 aa에 접근할 때는 aa가 아직 초기화되지 않았으므로 undefined이 출력된다.

참고자료


'JavaScript' 카테고리의 다른 글

[JavaScript] Trailing Comma 번역자료  (0) 2017.10.02
[JavaScript] 생성자 함수  (0) 2017.02.27
[JavaScript] 배열 연결  (0) 2017.01.26
[JavaScript] 동등, 일치 연산자  (0) 2016.10.04

+ Recent posts