Javascript

h232ch·2022년 7월 17일
2

frontend

목록 보기
2/3
post-thumbnail

자바스크립트 개요


자바스크립트 개요


자바스크립트

  • 객체(Object) 기반의 스크립트 언어
  • 웹의 동작 구현 가능 (정적인 구현은 HTML, CSS로 수행)
  • 주로 웹 브라우저에서 사용되지만 Node.js와 같은 프레임워크로 서버 사이드 프로그래밍 가능
  • 대부분의 웹 브라우저에 “자바스크립트 인터프리터”가 내장되어 있음
<!DOCTYPE html>
<html lang="ko">

<head>
    <meta charset="UTF-8">
    <title>JavaScript Intro</title>
    <script>
        document.write("<h2>여러분을 환영합니다!!</h2>")
    </script>
</head>

<body>
<noscript>
    <p>여러분의 웹 브라우저가 자바스크립트를 지원하지 않습니다!</p>
</noscript>

</body>
</html>

자바스크립트 기초


자바스크립트의 역사

  • 1995년 넷스케이프의 브렌던 아이크에 의해 만들어 짐
  • 처음에 모카라는 이름으로 개발되었으나 최종적으로 자바스크립트라는 이름으로 변경

자바스크립트의 특징

  • 객체 기반의 스크립트 언어
  • 동적이며 타입을 명시할 필요가 없는 인터프리터 언어
  • 객체 지향형 프로그래밍과 함수형 프로그래밍을 모두 표현 가능

C언어나 자바와 같은 언어는 소스 파일 작성 후 해당 파일을 컴파일하여 사용자가 실행할 수 있는 실행 파일로 만들어 사용하지만 인터프리터 언어는 컴파일 작업 수행 없이 소스 코드를 바로 실행할 수 있는 언어를 의미하며 자바스크립트는 웹 브라우저에 포함된 자바스크립트 인터프리터가 소스 코드를 직접 해석하고 바로 실행함


프로토타입 기반 언어

https://evan-moon.github.io/2019/10/23/js-prototype/

Call by value, Call by reference
https://velog.io/@xylopeofficial/Call-By-Value-Call-By-Reference

자바는 매개변수를 넘길 때 매개변수에 참조값을 복사하여 전달(Call by value)함 Call by reference라면 매개변수에 참조값을 복사하여 전달하는 방식이 아닌 참조값 자체를 넘겨야 함


자바와 자바스크립트

자바와 자바 스크립트는 이름이 비슷하여 관련있는 언어로 생각하기 쉬우나 서로 관련이 없으며 비슷한 점보다는 다른 점이 훨씬 많다. 문법상 비슷한 부분은 두 언어 모두 C언어를 기반으로 만들어졌기 때문이다.

자바자바스크립트
컴파일 언어인터프리터 언어
타입 검사 엄격타입을 명시하지 않음
클래스 기반의 객체 지향 언어프로토 타입 기반의 객체 지향 언어

자바스크립트 표준

1996년 넷스케이프는 자바스크립트를 국제 표준안으로 만들기 위해 ECMA(European Computer Manufacturers Association)에 제출하였고 그 결과 ECMAScript라는 새로운 표준을 제정함. 그 결과로 첫 번째 버전인 ECMA-262를 1997년 공표함.


자바스크립트 소개


자바스크립트 소개

자바스크립트는

  1. HTML의 ‘내용’을 변경할 수 있음
  2. HTML의 ‘속성’을 변경할 수 있음
  3. HTML의 ‘스타일’을 변경할 수 있음

자바스크립트 문법


프로그래밍이란?

프로그램은 컴퓨터가 실행할 수 있는 명령(instruction)으로 이뤄진다. 컴퓨터 프로그래밍에서 컴퓨터가 실행할수 있는 명령들을 실행문(statement)이라고 한다. 프로그램이란 특정 결과를 얻기 위해서 컴퓨터에 의해 실행되는 실행문의 집합이라고 할 수 있음.


자바스크립트 문법

자바스크립느의 실행문은 세미콜론(;)으로 구분된다.

var x = 10;
var result = x + 3;

자바 스크립트는 대소분자를 구분한다.

자바스크립트에서 변수나 함수의 이름, 예약어 등을 작성하거나 사용할 때는 대소문자를 정확히 구분해야 함

var javascript = 10; // 변수 javascript와 JavaScript는 서로 다른 두 개의 변수로 인식됨.
var JavaScript = 20;
Var Script = 30; // 변수의 선언은 var 키워드로만 할 수 있으면 Var는 동작하지 않음.

리터럴(literal)

리터를은 직접 표현되는 값 그 자체를 의미함

다음 예제에서 등장하는 값은 모두 리터럴이다.

12            // 숫자 리터럴
"JavaScript"  // 문자열 리터럴
'안녕하세요'  // 문자열 리터럴
true          // 불리언 리터럴

식별자(identifier)

식별자는 변수나 함수의 이름을 작성할 때 사용하는 이름을 의미함

자바스크립트에서 식별자는 영문자(대소문자), 숫자,언더스코어(_) 또는 달러($)만을 사용할 수 있음

자바스크립에서 식별자는 숫자와 식별자의 구별을 빠르게 할 수 있도록 숫자로는 시작할 수 없음
자바스크립트는 유니코드 문자셋을 사용함


식별자 작성 방식

자바스크립트에서는 아래의 방식으로 식별자를 작성함

  1. Camel Case (thisIsValue)
  2. Underscore Case (this_is_value)

자바스크립트에서는 관행적으로 Camel Case 방식을 많이 사용함

var firstVar = 10;           // Camel Case 방식

function my_first_func {     // Underscore Case 방식
    var firstLocalVar = 20;  // Camel Case 방식
}

자바스크립트에서 하이픈(-)은 뺄셈을 위해 예약된 키워드이므로, 식별자를 작성할 때는 사용할 수 없음


키워드(keyword)

몇몇 단어들은 특별한 용도로 사용하기 위해 미리 예약하고 있음. 이렇게 미리 예약된 단어들을 키워드 또는 예약어라고 하며 이러한 키워드들은 프로그램 내에서 식별자로 사용 불가함

var firstVar = 10;      // var는 변수의 정의를 위해 예약된 키워드입니다.
function myFirstFunc {  // function은 함수의 정의를 위해 예약된 키워드입니다.
    var secondVar = 20; // var는 변수의 정의를 위해 예약된 키워드입니다.
}

주석(comment)

주석(comment)이란 코드 내에 삽입된 일종의 설명문이다.

var x = 10;

// var y = 20; 한 줄의 주석문 : 이 부분은 실행되지 않을 것입니다.

/*
x = x + y;
여러 줄의 주석문 :
이 부분 또한 실행되지 않을 것입니다.
*/
document.getElementById("text").innerHTML = x;

주석 내부로 또 다른 여러 줄 주석을 삽일할 수 없음 (삽입 할 경우 syntax error 발생)

/* 여러 줄
    /* 또 다른 여러 줄 주석입니다. */
주석입니다. */

자바스크립트 출력


자바스크립트 출력

자바스크립트는 여러 방법을 통해 결과물을 HTML 페이지에 출력함

자바스크립트에서 사용할 수 있는 출력 방법은 다음과 같다.

  1. window.alert() 메서드
  2. HTML DOM 요소를 이용한 innerHTML 프로퍼티
  3. document.write() 메소드
  4. console.log() 메소드

window.alert() 메소르

자바스크립트에서 가장 간단하게 데이터를 출력하는 방법은 windows.alert() 메소드를 이용하는 것이다.

해당 메소드는 브라우저와는 별도의 대화상자를 띄워 사용자에게 데이터를 전달해 줌

<script>

    function alertDialogBox() {

        alert("확인을 누를 때까지 다른 작업을 할 수 없어요!");

    }

</script>

HTML DOM 요소를 이용한 innerHTML 프로퍼티

실제 자바스크립트 코드에서 출력을 위해 가장 많이 사용되는 방법은 HTML DOM 요소를 이용한 innerHTML 프로퍼티를 이용하는 방법이다. 우선 document 객체의 getElementsByID()나 getElementsByTagName() 등의 메서드를 사용해서 HTML 요소를 선택한다. 그리고 innerHTML 프로퍼티를 이용하여 선택된 HTML 요소의 내용이나 속성값 등을 손쉽게 변경할 수 있다.

<script>
    function changeContent() {
        var str = document.getElementById("text");
        str.innerHTML = "이 문장으로 바뀌었습니다!";
    }
</script>

<p id="text">
    test text
    <button onclick="changeContent()">Click</button>
</p>

document.write() 메소드

document.write() 메소드는 웹페이지가 로딩될 때 실행되면, 웹페이지에 가장 먼저 데이터를 출력한다.

따라서 document.write()는 주로 디버깅을 위해 사용된다.

<script>
    document.write(4 * 5);
</script>

하지만 웹페이지의 모든 내용이 로딩된 이후 해당 메소드가 실행되면, 웹페이지 내에 먼저 로딩된 모든 데이터를 지우고 자신의 데이터를 출력한다. 따라서 해당 메소드를 테스트 이외의 용도로 사용할 때는 충분히 주의해야 함

<button onclick="document.write(4 * 5)">버튼을 눌러보세요!</button>

console.log() 메소드

console.log() 메소드는 웹브라우저의 콘솔을 통해 데이터를 출력해 준다.

대부분의 주요 웹브라우저에서는 F12를 누른 후 메뉴에서 콘솔을 클릭하면 해당 기능을 사용할 수 있다.

이러한 콘솔 화면을 통한 데이터 출력은 좀 더 자세한 사항까지 출력하여 디버깅에 많은 도움이 된다.

<p>F12를 눌러서 콘솔 화면을 열면 결과를 확인할 수 있습니다.</p>
<script>
    console.log(4 * 5);
</script>

자바스크립트를 적용하는 방법

HTML 문서에 자바스크립트 코드를 적용하는 방법에는 다음과 같은 방법이 있다.

  1. 내부 자바스크립트 코드로 적용
  2. 외부 자바스크립트 파일로 적용

내부 자바스크립트 코드

자바스크립트 코드는

<script>
    document.getElementById("text").innerHTML = "여러분을 환영합니다!";
</script>

이렇게 삽인된 자바스크립트 코드는 HTML 문서의 태그나 태그, 또는 양쪽 모두에 위치 할 수 있음 다음 예제는 HTML 문서의 와 에 삽입된 코드 예제이다.

<head>
    <meta charset="UTF-8">
    <title>JavaScript Apply</title>
    <script>
        function printDate() {
            document.getElementById("date").innerHTML = Date();
        }
    </script>
</head>
<body>
    <p>자바스크립트를 이용하면 현재 날짜와 시간 정보에도 손쉽게 접근할 수 있어요!</p>
    <button onclick="printDate()">현재 날짜와 시간 표시하기!</button>
    <p id="date"></p>
    <script>
        function printDate() {
            document.getElementById("date").innerHTML = Date();
        }
    </script>
</body>


외부 자바스크립트 파일

자바스크립트 코드는 HTML 문서의 내부뿐만 아니라 외부 파일로 생성하여 삽입 가능하다.

외부에 작성된 자바스크립트 파일은 .js 확장자를 사용하여 저장하며 해당 파일을 적용하고 싶은 모든 웹 페이지에

// example.js

function printDate() {
    document.getElementById("date").innerHTML = Date();
}
<head>
    <meta charset="UTF-8">
    <title>JavaScript Apply</title>
    <script src="/examples/media/example.js"></script>
</head>

외부 자바스크립트 파일을 사용하면 웹의 내용을 담당하는 HTML 코드로부터 웹 동작을 구현하는 자바스크립트 코드를 분리할 수 있다. 이렇게하면 HTML 코드와 자바스크립트 코드를 각각 읽기도 편해지고, 유지보수도 쉬워진다.


2. 타입


기본타입


기본타입

타입(data type)이란 프로그램에서 다룰 수 있는 값의 종류를 의미한다.

자바스크립트에서는 여러가지 형태의 타입을 미리 정의하여 제공하고 있으며 이것을 기본 타입이라고 한다.

자바스크립트의 기본 타입은 크게 원시 타입과 객체 타입으로 구분 가능하다.

원시타입(primitive type)은 다음과 같다.

  1. 숫자(number)
  2. 문자열(string)
  3. 불리언(boolean)
  4. 심볼(symbol) : ECMAScript 6부터 제공됨
  5. undefined

객체 타입(objective type)은 다음과 같다.

  1. 객체(object)
var num = 10;          // 숫자
var myName = "홍길동"; // 문자열
var str;               // undefined

숫자(number)

다른 언어와는 달리 정수와 실수를 따로 구분하지 않고 모든 수를 실수 하나로 표현한다.

또한 매우 큰 수나 매우 작은 수를 표현할 경우 e 표기법을 사용할 수 있다.

var firstNum = 10;     // 소수점을 사용하지 않은 표현
var secondNum = 10.00; // 소수점을 사용한 표현
var thirdNum = 10e6;   // 10000000
var fourthNum = 10e-6; // 0.00001

문자열(string)

문자열은 큰따옴표(””)나 작은따옴표(’’)로 둘러싸인 문자의 집합을 의미한다.

큰따옴표는 작은따옴표로 둘러싸인 문자열에만 포함될 수 있으며 작은따옴표는 큰따옴표로 둘러싸인 문자열에만 포함된다.

var firstStr = "이것도 문자열입니다.";      // 큰따옴표를 사용한 문자열
var secondStr = '이것도 문자열입니다.';     // 작은따옴표를 사용한 문자열
var thirdStr = "나의 이름은 '홍길동'이야."  // 작은따옴표는 큰따옴표로 둘러싸인 문자열에만 포함될 수 있음.
var fourthStr = '나의 이름은 "홍길동"이야.' // 큰따옴표는 작은따옴표로 둘러싸인 문자열에만 포함될 수 있음.

자바스크립트에서는 숫자와 문자를 더할 수도 있다. 이럴경우 자바스크립트는 숫자를 문자열로 자동 변환하여 두 문자열을 연결하는 연산을 수행한다.

var num = 10;
var str = "JavaScript";
document.getElementById("result").innerHTML = (num + str); // 10JavaScript

불리언(boolean)

불리언 값은 참과 거짓을 표현한다.

불리언 값은 예약어인 true와 false를 사용하여 나타낼 수 있다.

var firstNum = 10;
var secondNum = 11;
document.getElementById("result").innerHTML = (firstNum == secondNum); // false

심볼(symbol)

심볼 타입은 ECMAScript 6부터 새롭게 추가된 타입니다.

심볼은 유일하고 변경할 수 없는 타입으로 객체의 프로퍼티를 위한 식별자로 사용할 수 있다.

var sym = Symbol("javascript");  // symbol 타입
var symObj = Object(sym);        // object 타입

typeof 연산자

typeof 연산자는 피연산자의 타입을 반환하는 피연산자가 단 하나뿐인 연산자이다.

typeof 10;        // number 타입
typeof "문자열";  // string 타입
typeof true;      // boolean 타입
typeof undefined; // undefined 타입
typeof null;      // object 타입

null과 undefined

자바스크립트에서 null이란 object 타입이며 아직 값이 정해지지않은 것을 의미한다.

또한 undefined란 null과는 다르게 타입이 정해지지않은 것을 의미한다. 따라서 자바스크립에서 undefined는 초기화되지 않은 변수나 존재하지 않는 값에 접근할 때 반환된다.

var num;          // 초기화하지 않았으므로 undefined 값을 반환함.
var str = null;   // object 타입의 null 값
typeof secondNum; // 정의되지 않은 변수에 접근하면 undefined 값을 반환함.

null과 undefined는 동등 연산자(==)와 일치 연산자(===)로 비교할 때 그 결괏값이 다르므로 주의해야 함

null과 undefined는 타입을 제외하면 같은 의미지만 타입이 다르므로 일치하지는 않습니다.

null ==  undefined; // true
null === undefined; // false

객체(object)

자바스크립트의 기본 타입은 객체(object)이다. 객체란 실생활에서 우리가 인식할 수 있는 사물로 이해할수 있다. 객체는 여러 프로퍼티(property)나 메소드(method)를 같은 이름으로 묶어놓는 일종의 집합체이다.

var dog = { name: "해피", age: 3 }; // 객체의 생성
// 객체의 프로퍼티 참조
document.getElementById("result").innerHTML =
    "강아지의 이름은 " + dog.name + "이고, 나이는 " + dog.age + "살 입니다.";

타입변환


타입변환 (type conversion)

자바스크립트는 타입 검사가 매우 유연한 언어이다. 변수는 타입이 정해져 있지 않으며 같은 변수에 다른 타입의 값을 다시 대입할 수도 있다.

var num = 20; // Number 타입의 20
num = "이십"; // String 타입의 "이십"
var num;      // 한 변수에 여러 번 대입할 수는 있지만, 변수의 재선언은 할 수 없습니다. 재선언문은 무시됩니다.

묵시적 타입 변환(implicit type conversion)

자바스크립트는 특정 타입의 값을 기대하는 곳에 다른 타입의 값이 오면 자동으로 타입을 변환하여 사용한다. 문자열 값이 오길 기대하는 곳에 숫자가 오더라도 자바스크립트는 알아서 숫자를 문자열로 변환하여 사용한다.

10 + "문자열"; // 문자열 연결을 위해 숫자 10이 문자열로 변환됨.
"3" * "5";     // 곱셈 연산을 위해 두 문자열이 모두 숫자로 변환됨.
1 - "문자열";  // NaN

세번째 예제에서 뺼셈 연산을 위해 문자열이 숫자로 변환되어야 하나 해당 문자열은 두번째 예제의 문자열과 달리 숫자로 변환될 수 없는 문자열이기 때문에 자바스크립트는 NaN 값을 반환한다.

NaN은 Not a Number의 축양형으로 정의되지 않은 값이나 표현할 수 없는 값이라는 의미를 가진다. 이러한 NaN은 Number 타입의 값으로 0을 0으로 나누거나 숫자로 변환 분가능한 피연산자로 산술 연산을 시도하는 경우 반환되는 읽기 전용 값이다.


명시적 타입 변환(explicit type conversion)

자바스크립트에서 묵시적 타입변환을 많이 사용하지만 명시적으로 타입을 변환할 방법도 제공한다. 명시적 타입 변환을 위해 자바스크립트가 제공하는 전역 함수는 다음과 같다.

  1. Number()
  2. String()
  3. Boolean()
  4. Object()
  5. parseInst()
  6. parseFloat()
Number("10"); // 숫자 10
String(true); // 문자열 "true"
Boolean(0);   // 불리언 false
Object(3);    // new Number(3)와 동일한 결과로 숫자 3

숫자를 문자열로 변환

숫자를 문자열로 변환하는 가장 간단한 방법은 String() 함수를 사용하는 것이다. 또한 null과 undefined를 제외한 모든 타입의 값이 가지고 있는 toString()메소드를 사용할 수도 있다.

숫자(Number) 객체는 숫자를 문자열로 변환하는 다음과 같은 메소드를 별도로 제공한다.

  1. toExponential()
  2. toFixed()
  3. toPercision()
Method설명
toExponential()정수 부분은 1자리, 소수 부분은 입력받은 수만큼 e표기법을 사용하여 숫자를 문자열로 변환함
toFixed()소수 부분을 입력받은 수만큼 사용하여 숫자를 문자열로 변환함
toPercision()입력받은 수만큼 유효 자릿수를 사용하여 숫자를 문자열로 변환함

메소드란 객체의 프로퍼티 값으로 함수를 갖는 프로퍼티를 의미한다.


불리언 값을 문자열로 변환

String(true);     // 문자열 "true"
false.toString(); // 문자열 "false"

날짜를 문자열이나 숫자로 변환

날짜를 문자열로 변환하는 방법에는 String() 함수와 toString() 메소드를 사용하는 방법이 있다. 자바스크립트에서 날짜(Date) 객체는 문자열과 숫자로 모두 변환할 수 있는 유일한 타입니다. 날짜 객체는 날짜를 숫자로 변환하는 다음과 같은 메소드를 별도로 제공한다.

  1. getDate()
  2. getDay()
  3. getDate()
  4. getDay()
  5. getFullYear()
  6. getMonth()
  7. getTime()
  8. getHours()
  9. getMinutes()
  10. getSeconds()
  11. getMilliseconds()
메소드설명
getDate()날짜 중 일자를 숫자로 반환함. (1 ~ 31)
getDay()날짜 중 요일을 숫자로 반환함. (일요일 : 0 ~ 토요일 : 6)
getFullYear()날짜 중 연도를 4자리 숫자로 반환함. (yyyy년)
getMonth()날짜 중 월을 숫자로 반환함. (1월 : 0 ~ 12월 : 11)
getTime()1970년 1월 1일부터 현재까지의 시간을 밀리초(millisecond) 단위의 숫자로 반환함.
getHours()시간 중 시를 숫자로 반환함. (0 ~ 23)
getMinutes()시간 중 분을 숫자로 반환함. (0 ~ 59)
getSeconds()시간 중 초를 숫자로 반환함. (0 ~ 59)
getMilliseconds()시간 중 초를 밀리초(millisecond) 단위의 숫자로 반환함. (0 ~ 999)
String(Date());        // Mon May 16 2016 19:35:25 GMT+0900
Date().toString();     // Mon May 16 2016 19:35:25 GMT+0900
var date = new Date(); // Date 객체 생성
date.getFullYear();    // 2016
date.getTime();        // 1463394925632 -> 1970년 1월 1일부터 현재까지의 시간을 밀리초 단위의 숫자로 반환함.

문자열을 숫자로 변환

문자열을 숫자로 변환하는 가장 간단한 방법은 Number() 함수를 사용하는 것이다. 자바스크립트는 문자열을 숫자로 변환해 주는 두개의 전역 함수를 별도로 제공한다.

  1. parseInt()
  2. parseFloat()
함수설명
parseInt()문자열을 파싱하여 특정 진법의 정수를 반환함.
parseFloat()문자열을 파싱하여 부동 소수점 수를 반환함.

불리언 값을 숫자로 변환

Number(true);  // 숫자 1
Number(false); // 숫자 0

변수


변수의 선언과 초기화

변수(variable)란 데이터(data)를 저장할 수 있는 메모리 공간을 의미하며 그 값이 변경될 수 있다. 자바스크립트에서는 var 키워드를 사용하여 변수를 선언한다.

자바스크립트에서는 선언되지 않은 변수를 사용하려고 하거나 접근하려고 하면 오류가 발생한다. 단 선언되지 않은 변수를 초기화할 경우에는 자동으로 선언을 먼저 한 후 초기화를 진행한다.

var month; // month라는 이름의 변수 선언
date = 25; // date라는 이름의 변수를 묵시적으로 선언

선언된 변수는 나중에 초기화할 수도 있고 선언과 동시에 초기화 할 수도 있다.

var month;     // 변수의 선언
var date = 25; // 변수의 선언과 동시에 초기화
month = 12;    // 변수의 초기화

쉼표(,) 연산자를 이용해서 여러 변수를 동시에 선언하거나 초기화할 수도 있다.

var month, date;             // 여러 변수를 한 번에 선언
var hours = 7, minutes = 15; // 여러 변수를 선언과 동시에 초기화
month = 10, date = 5;        // 여러 변수를 한 번에 초기화

변수의 타입과 초깃값

변수는 타입이 정해져 있지 않으며 같은 변수에 다른 타입의 값을 다시 대입할 수도 있다. 이렇게 한 변수에 다른 타입의 값을 여러번 대입할 수 있지만 한번 선언된 변수는 재선언 할 수 없다.

var num = 10;        // 변수의 선언과 함께 초기화
num = [10, 20, 30];  // 배열 대입
var num;             // 이 재선언문은 무시됨.

배열(array)이란 여러 값들로 이뤄진 하나의 집합을 의미한다.

선언만 되고 초기화하지 않은 변수는 undefined 값을 갖는다.

var num;  // undefined
num = 10; // 10

변수의 이름

자바스크립트에서 변수는 이름을 가지고 식별하므로 변수의 이름은 식별자(identifier)이다. 변수의 이름은 영문자(대소문자), 숫자, 언더스코어(_) 또는 달러($)로만 구성됩니다. 또한 숫자와의 구분을 빠르게 하려고 숫자로는 시작할 수 없다. 이러한 변수의 이름은 대소문자를 구분하며 자바스크립트 언어에서 예약된 키워드는 이름으로 사용할 수 없다.

3. 연산자 (생략)


기타 연산자


삼항 연산자(ternary operator)

var x = 3, y = 5;
var result = (x > y) ? x : y   // x가 더 크면 x를, 그렇지 않으면 y를 반환함.
document.write("둘 중에 더 큰 수는 " + result + "입니다.");

쉼표 연산자

// 루프마다 i의 값은 1씩 증가하고, 동시에 j의 값은 1씩 감소함.
for (var i = 0, j = 9; i <= j; i++, j--) {
    document.write("i의 값은 " + i + "이고, j의 값은 " + j + "입니다.<br>");
}

Delete 연산자

피연산자인 객체, 객체의 프로퍼티 또는 배열의 요소 등을 삭제해 준다.
피연산자가 삭제에 성공할 경우 True, 실패할 경우 False를 반환한다.

4. 제어문


조건문


조건문이란 프로그램 내에서 주어진 표현식의 결과에 따라 별도의 명령을 수행하도록 제어하는 실행문이다.

자바스크립트에서 사용 가능한 조건문의 형태는 아래와 같다.

  1. if 문
  2. if / else 문
  3. if / else if / else 문
  4. switch 문

if 문

var x = 10, y = 20;

if (x == y) {
    document.write("x와 y는 같습니다.");
}
if (x < y) {
    document.write("x가 y보다 작습니다.");
}
if (x > y) // 실행될 실행문이 한 줄뿐이라면 중괄호({})를 생략할 수 있음.
    document.write("x가 y보다 큽니다.");

else 문

var x = 10, y = 20;

if (x == y) {
    document.write("x와 y는 같습니다.");
} else {
    if (x < y)
        document.write("x가 y보다 작습니다.");
    else // 실행될 실행문이 한 줄뿐이라면 중괄호({})를 생략할 수 있음.
        document.write("x가 y보다 큽니다.");
}

else if 문

var x = 10, y = 20;

if (x == y) {
    document.write("x와 y는 같습니다.");
} else if (x < y) {
    document.write("x가 y보다 작습니다.");
} else { // x > y인 경우
    document.write("x가 y보다 큽니다.");
}

switch 문

var x = 10;

switch (typeof x) {
    case "number":
        document.write("변수 x의 타입은 숫자입니다.");
        break;

    case "string":
        document.write("변수 x의 타입은 문자열입니다.");
        break;

    case "object":
        document.write("변수 x의 타입은 객체입니다.");
        break;

    default:
        document.write("변수 x의 타입을 잘 모르겠네요...");
        break;
}
var day = new Date().getDay(); // 오늘의 요일을 반환함. (일요일: 0 ~ 토요일: 6)

switch (day) {
    case 1: // 월요일인 경우
    case 2: // 화요일인 경우
    case 3: // 수요일인 경우
    case 4: // 목요일인 경우
    default: // 0부터 6까지의 값이 아닌 경우
        document.write("아직도 주말은 멀었네요... 힘내자구요!!");
        break;
    case 5: // 금요일인 경우
        document.write("오늘은 불금이네요!!");
        break;
    case 6: // 토요일인 경우
    case 0: // 일요일인 경우
        document.write("즐거운 주말에도 열심히 공부하는 당신~ 최고에요!!");
        break;
}

반복문


반복문이란 프로그램 내에서 똑같은 명령을 일정 횟수만큼 반복하여 수행하도록 제어하는 실행문이다.

자바스크립트에서 사용 가능한 반복문의 형태는 아래와 같다.

  1. while 문
  2. do / while 문
  3. for 문
  4. for / in 문
  5. for / of 문

while 문

while 문은 특정 조건이 만족할 때까지 계속 주어진 실행문을 반복 실행한다.

var i = 1;

while (i < 10) { // 변수 i가 10보다 작을 때만 while 문을 반복함.
    document.write(i + "<br>");
    i++; // 반복할 때마다 변수 i를 1씩 증가시켜 변수 i가 10보다 커지면 반복문을 종료함.
}

while 문 내부에 표현식의 결과를 변경하는 실행문이 존재하지 않을 경우 프로그램은 무한 루프에 빠지게 된다. 의도하지 않은 경우라면 반드시 피해야 하는 상황이다. 따라서 while 문을 작성할 때는 표현식의 결과가 어느 순간에는 거짓(false)를 갖도록 변경하는 실행문을 반드시 포함해야 한다.

while 문에서 실행될 실행문이 한 줄 뿐이라면 중광호({})를 생략할 수 있다.

do / while 문

while 문은 루프에 진입하기 전에 먼저 표현식부터 검사한다. 하지만 do / while 문은 먼저 루프에 한번 실행한 후에 표현식을 검사한다. do / while 문은 표현식의 결과와 상관없이 무조건 한 번은 루프를 실행한다.

var i = 1, j = 1;

while (i > 3) { // 변수 i의 초깃값은 1이기 때문에 이 while 문은 한 번도 실행되지 않음.
    document.write("i : " + (i++) + "<br>");
}

do { // 변수 j의 초깃값은 1이기 때문에 이 do / while 문은 단 한 번만 실행됨.
    document.write("j : " + (j++) + "<br>");
} while (j > 3);

for 문

for 문은 while 문과 다르게 자체적으로 치기식, 표현식, 증감식을 모두 포함하고 있는 반복문이다.

for (var i = 1; i < 10; i++) {
    document.write(i + "<br>");
}

for / in 문

for / in 문은 일반적인 for 문과는 다른 형태의 반복문이다. for / in 문은 해당 객체의 모든 열거 가능한 프로퍼티(enumerable properties)를 순회할 수 있도록 도와준다.

열거 가능한 프로퍼티란 내부적으로 enumerable 플래그가 true로 설정된 프로퍼티를 의미하고 이러한 프로퍼티들은 for / in 문으로 접근할 수 있다.

이 반복문은 루프마다 객체의 열거 가능한 프로퍼티의 이름을 지정된 변수에 대입한다. 이렇게 대입받은 변수를 이용하면 루프 안에서 격체의 열거 가능한 프로퍼티에 순차적으로 접근 가능하다.

var arr = [3, 4, 5];
for (var i = 0; i < arr.length; i++) { // 배열 arr의 모든 요소의 인덱스(index)를 출력함.
    document.write(i + " ");
}

for (var i in arr) { // 위와 같은 동작을 하는 for / in 문
    document.write(i + " ");
}
var obj = { name : "이순신", age : 20 };
for (var i in obj) {
    document.write(i + "<br>");
}

for / in 문은 해당 객체가 가진 모든 프로퍼티를 반환하는 것이 아닌, 오직 열거할 수 있는 프로퍼티만을 반환한다.

for / of 문

for / of 문은 반복할 수 있는 객체(iterable objects)를 순회할 수 있도록 해주는 반복문이다.

자바스크립트에는 Array, Map, Set, arguments와 같이 반복할 수 있는 객체의 종류가 존재한다.

이 반복문은 루프마다 객체의 열거할 수 있는 프로퍼티 값을 지정된 변수에 대입한다.

var arr = [3, 4, 5];

for (var i = 0; i < arr.length; i++) { // 배열 arr의 모든 요소의 인덱스(index)를 출력함.
    document.write(arr[i] + " ");
}

for (var value of arr) { // 위와 같은 동작을 하는 for / of 문
    document.write(value + " ");
}

for / of 문은 익스플로러에서 지원하지 않는다.

for / of 문을 사용하여 Set 객체의 프로퍼티에 접근하는 예제이다.

var arr = new Set([1, 1, 2, 2, 3, 3]);
for (var value of arr) {
    document.write(value + " ");
}

5. 배열


배열의 기초


배열이란?

자바스크립트에서 배열은 이름과 인덱스로 참조되는 정렬된 값의 집합으로 정의된다.

배열을 구성하는 각각의 값을 배열 요소(element)라고 하며 배열에서의 위치를 가르키는 숫자를 인덱스(index)라고 한다. 자바스크립트에서 배열의 특징은 다음과 같다.

  1. 배열 요소의 타입이 고정되어 있지 않으므로 같은 배열에 있는 배열 요소끼리 타입이 서로 다를 수 있다.
  2. 배열 요소의 인덱스가 연속적이 않아도 되며 따라서 특정 배열 요소가 비어있을 수 있다.
  3. 자바스크립에서 배열은 Array 객체로 다뤄진다.

배열의 생성

1. var arr = [배열요소1, 배열요소2,...];          // 배열 리터럴을 이용하는 방법
2. var arr = Array(배열요소1, 배열요소2,...);     // Array 객체의 생성자를 이용하는 방법
3. var arr = new Array(배열요소1, 배열요소2,...); // new 연산자를 이용한 Array 객체 생성 방법

위 세가지 방법은 모두 같은 결과의 배열을 만들어 낸다.

var arrLit = [1, true, "JavaScript"];             // 배열 리터럴을 이용하는 방법
var arrObj = Array(1, true, "JavaScript");        // Array 객체의 생성자를 이용하는 방법
var arrNewObj = new Array(1, true, "JavaScript"); // new 연산자를 이용한 Array 객체 생성 방법

document.write(arrLit + "<br>");                  // 1,true,JavaScript
document.write(arrObj + "<br>");                  // 1,true,JavaScript 
document.write(arrNewObj);                        // 1,true,JavaScript

배열의 참조

var arr = ["JavaScript"]; // 요소가 하나뿐인 배열을 생성함.
var element = arr[0];     // 배열의 첫 번째 요소를 읽어서 대입함.

arr[1] = 10;      // 배열의 두 번째 요소에 숫자 10을 대입함. 배열의 길이는 1에서 2로 늘어남.
arr[2] = element; // 배열의 세 번째 요소에 변수 element의 값을 대입함. 배열의 길이는 2에서 3으로 늘어남.

document.write("배열 arr의 요소에는 [" + arr + "]가 있습니다.<br>"); // 배열의 요소를 모두 출력함.
document.write("배열 arr의 길이는 " + arr.length + "입니다.<br>");   // 배열의 길이를 출력함.

delete arr[2];    // 배열의 세 번째 요소를 삭제함. 하지만 배열의 길이는 변하지 않음.
document.write("배열 arr의 요소에는 [" + arr + "]가 있습니다.<br>"); // 배열의 요소를 모두 출력함.
document.write("배열 arr의 길이는 " + arr.length + "입니다.");       // 배열의 길이를 출력함.

배열 요소의 추가

var arr = [1, true, "Java"];

arr.push("Script");           // push() 메소드를 이용하는 방법
document.write(arr + "<br>"); // 1,true,Java,Script
 
arr[arr.length] = 100;        // length 프로퍼티를 이용하는 방법
document.write(arr + "<br>"); // 1,true,Java,Script,100

arr[10] = "자바스크립트";     // 특정 인덱스를 지정하여 추가하는 방법
document.write(arr + "<br>"); // 1,true,Java,Script,100,,,,,,자바스크립트
document.write(arr[7]);       // undefined

인덱스에 대응하는 배열의 요소가 없는 부분을 배열의 홀이라고 하며 이러한 홀을 호출하는 경우 undefined 값을 반환하게 된다.

배열의 순회

var arr = [1, true, "JavaScript"];

var result = "<table><tr>";
for (var idx in arr) {
    result += "<td>" + arr[idx] + "</td>";
}

result += "</tr></table>";
document.write(result);

Array 객체

자바스크립트에서 배열은 정렬된 값들의 집합으로 정의되며 Array 객체로 다룬다.

var arr = new Array(10, "문자열", false);

document.write((typeof arr) + "<br>");    // object
document.write((typeof arr[0]) + "<br>"); // number
document.write((typeof arr[1]) + "<br>"); // string
document.write(typeof arr[2]);            // boolean

배열의 활용


희소 배열

희소 배열이란 배열에 속한 요소의 위치가 연속적이 않는 배열을 의미한다. 따라서 배열 length 프로퍼티 값보다 배열 요소의 개수가 언제나 적다.

var arr = new Array(); // 빈 배열 객체를 생성함.
arr[99] = "JavaScript" // 배열 arr의 100번째 위치에 문자열을 삽입함.
// 100번째 요소를 삽입했기 때문에 배열의 길이는 100으로 늘어남.
document.write("배열의 길이는 " + arr.length + "입니다.");

다차원 배열

다차원 배열이란 배열 요소가 또 다른 배열인 배열을 의미한다.

var arr = new Array(3);      // 3개의 요소를 가지는 배열을 생성함.
for (var row = 0; row < 3; row++) {
    arr[row] = new Array(4); // 각각의 요소마다 또다시 4개의 요소를 가지는 배열을 생성함.
    for (var column = 0; column < 4; column++) {
        arr[row][column] = "[" + row + "," + column + "]"; // 각각의 배열 요소를 생성함.
        document.write(arr[row][column] + " ");            // 각 배열 요소에 접근함.

    }

2차원 배열의 경우 [] 연산자를 두번 사용하여 참조 가능하다. (3차원 이상일 경우도 [] 연산자를 추가하여 참조)

연관 배열 (associative array)

자바스크립트에서는 배열의 인덱스에 0을 포함한 양의 정수만 사용 가능하다. 이렇게 숫자로된 인덱스 대신 문자열로 된 키를 사용하는 배열을 연관 배열이라고 한다.

대부분의 프로그래밍 언어가 지원하는 연관 배열을 자바스크립트는 별도로 제공하지 않는다. 대신 인덱스로 문자열을 사용하여 연관 배열처럼 사용할 수 있는 객체를 만들 수 있다. 하지만 이렇게 생성된 배열은 자바스크립트 내부적으로 Array 객체에서 기본 객체로 재선언된다.

var arr = [];     // 비어있는 배열을 생성함.

arr["하나"] = 1;  // 숫자 인덱스 대신에 문자열을 인덱스로 배열 요소를 추가함.
arr["참"] = true;
arr["자바스크립트"] = "JavaScript";

document.write(arr["참"]);  // 문자열을 인덱스로 배열 요소에 접근할 수 있음.
document.write(arr.length); // 연관 배열은 Array 객체가 아니므로 length 프로퍼티의 값이 0임.
document.write(arr[0]);     // undefined

이처럼 자바스크립트에서 연관 배열은 Array 객체가 아닌 기본 객체이므로 정확히 말하면 배열이 아니다. ECMAScript 6부터는 이러한 불편함을 해결하기 위해 새로운 데이터 구조인 Map 객체를 별도로 제공하고 있다.

배열 여부 확인

자바스크립트에서는 배열이라는 타입을 별도로 제공하지 않는다 배열은 객체 타입이 되며, typeof 연산자를 이용하면 ‘object’를 반환한다.

var arr = [1, true, "JavaScript"]; // 배열 생성
document.write(typeof arr);        // object

따라서 자바스크립트에서는 해당 변수가 배열인지 여부를 확인할 수 있도록 다음과 같은 방법을 제공한다.

  1. Array.isArray() 메소드
  2. instancef 연산자
  3. constructor 프로퍼티

ECMAScript 5부터 Array 클래스에 isArray()라는 배열 여부를 확인할 수 있는 메소드가 추가되었다.

document.write(Array.isArray(arr));      // true
document.write(Array.isArray("문자열")); // false

하지만 구형 버전의 브라우저에서는 ECMAScript 5를 지원하지 않으므로 해당 코드가 정상적으로 동작하지 않을 수 있다. 따라서 이때는 instanceof 연산자를 사용하여 해당 변수가 Array 객체인지 판단해야 한다.

document.write(arr instanceof Array); // true
document.write(123 instanceof Array); // false

또한 Array 객체의 constructor 프로퍼티를 사용하여 배열 여부를 확인할 수 있다.

function isArray(a) {
    return a.constructor.toString().indexOf("Array") > -1;
}

 
var arr = [1, true, "JavaScript"];          // 배열 생성
document.write(arr.constructor);            // constructor 프로퍼티의 값 출력
document.write(arr.constructor.toString()); // function Array() {[native code]}
document.write(arr.constructor.toString().indexOf("Array")); // 10
document.write(isArray(arr))                // true

indexOf 메서드는 해당 문자열의 위치를 숫자로 반환한다. 따라서 isArray 메서드는 contructor에 Array가 존재하지 않을 경우 -1을 반환하고 존재할 경우 0 이상의 값을 반환한다.

6. 함수


함수의 기초


함수(Function)란?

함수란 하나의 특별한 목적의 작업을 수행하도록 설계된 독립적인 블록을 의미한다. 이러한 함수는 필요 시 호출하여 해당 작업을 반복하여 수행할 수 있다.

function addNum(x, y) {
    return x + y;
}
document.write(addNum(2, 3));

자바스크립트 함수

자바스크립트에서는 함수도 하나의 타입(datatype)이다. 함수를 변수에 대입하거나, 프로퍼티를 지정하는 것도 가능하며 자바스크립트 함수는 다른 함수 내에 중첩되어 정의될 수 있다.

함수의 정의

자바스크립트에서 함수의 정의는 function 키워드로 시작되며, 다음과 같은 구성요소를 갖는다.

  1. 함수의 이름
  2. 괄호 안에 쉼표(,)로 구분되는 함수의 매개변수(parameter)
  3. 중괄호({})로 둘러싸인 자바스크립트 실행문

자바스크립트에서 함수를 정의하는 문법은 다음과 같다.

function 함수이름(매개변수1, 매개변수2,...) {
    함수가 호출되었을 때 실행하고자 하는 실행문;
}

함수 이름은 함수를 구분하는 식별자(identifier)이다. 매개변수란 함수를 호출할 때 인수(argument)로 전잘되는 값을 함수 내부에서 사용 가능하게 해주는 변수이다.

// addNum라는 이름의 함수를 정의함.
function addNum(x, y) {    // x, y는 이 함수의 매개변수임.
    document.write(x + y);
}
addNum(2, 3);              // addNum() 함수에 인수로 2와 3을 전달하여 호출함.

반환(return)문

자바스크립트에서 함수는 반환문을 포함할 수 있다. 이러한 반환문을 통해 호출자는 함수에서 실행된 결과를 전달받을 수 있다. 반환문 함수의 실행을 중단하고, 리턴 키워드 다음에 명시된 표현식의 값을 호출자에게 반환한다.
반환문읜 배열이나 객체를 포함한 모든 타입의 값을 반환할 수 있다.

function multiNum(x, y) {
    return x * y;         // x와 y를 곱한 결과를 반환함.
}
var num = multiNum(3, 4); // multiNum() 함수가 호출된 후, 그 반환값이 변수 num에 저장됨.
document.write(num);

함수의 호출

정의된 함수는 프로그램 내에서 호출되어야 실행되며 일반적인 함수의 호출은 함수의 정의문과 같은 형태로 호출할 수 있다.

function addNum(x, y) {
    return x + y;
}

var sum = addNum(3, 5); // 함수 addNum()을 호출하면서, 인수로 3과 5를 전달합니다.
                        // 함수의 호출이 끝난 뒤에는 그 반환값을 변수 sum에 대입합니다.

위 예제에서 인수(argument)로 전달된 숫자 3과 5는 함수에서 정의된 매개변수(parameter) x와 y에 각각 대입된다. 따라서 호출된 함수의 내부에서는 매개변수 x와 y에 각각 3과 5가 대입되어 계산된다.

값으로서의 함수

자바스크립트에서 함수는 문법적 구문일뿐만 아니라 갑(value)이기도 하다. 따라서 함수가 변수에 대입될 수 있으며, 다른 함수의 인수로 전달될 수도 있다.

function sqr(x) {                // 제곱의 값을 구하는 함수 sqr를 정의함.
    return x * x;
}

var sqrNum = sqr;                // 변수 sqrNum에 함수 sqr을 대입함.
document.write(sqr(4) + "<br>"); // 함수 sqr을 호출함.
document.write(sqrNum(4));       // 변수 sqrNum를 함수처럼 호출함.

변수의 유효 범위


자바스크립트에서 객체나 함수는 모두 변수이다. 변수의 유효 범위란 해당 변수, 객체 그리고 함수의 집합을 의미한다. 변수는 유효 범위에 따라 다음과 같이 구분된다.

  1. 지역 변수
  2. 전역 변수

지역 변수

지역 변수란 함수 내에서 선언된 변수를 말하고 선언된 함수 내에서만 유효하며 함수가 종료되면 메모리에서 사라진다. 함수의 매개변수 또한 함수 내에서 정의되는 지역 변수처럼 동작한다.

function localNum() {
    var num = 10; // 지역 변수 num에 숫자 10을 대입함.
    document.write("함수 내부에서 변수 num의 타입은 " + typeof num + "입니다.<br>"); // number
}

localNum();       // 함수 localNum()을 호출함.
document.write("함수의 호출이 끝난 뒤 변수 num의 타입은 " + typeof num + "입니다."); // undefined

자바스크립트에서 선언되지 않은 변수를 사용하려고 하거나 접근하려고 하면 오류가 발생한다. 하지만 선언되지 않은 변수에 대한 typeof 연산자의 결괏값은 undefined 값을 반환한다.


전역 변수

전역 변수란 함수 외부에서 선언된 변수를 가르키고 프로그램의 어느 영역에서나 접근 가능하다. 전역 변수는 홈페이지가 닫혀야만 메모리에서 사라진다.

var num = 10; // 전역 변수 num을 선언함.

function globalNum() {
    document.write("함수 내부에서 변수 num의 값은 " + num + "입니다.<br>"); // 10
    num = 20; // 전역 변수 num의 값을 함수 내부에서 변경함.
}

globalNum();  // 함수 globalNum()을 호출함.
document.write("함수의 호출이 끝난 뒤 변수 num의 값은 " + num + "입니다."); // 20

지역 변수를 선언할 때에는 반드시 var 키워드를 사용해야 한다. 함수 내부에서 var 키워드를 사용하지 않고 변수를 선언하면 해당 변수는 지역 변수가 아닌 전역 변수로 선언된다.

function globalNum() {
    num = 10; // var 키워드를 사용하지 않고 변수 num을 선언함.
    document.write("함수 내부에서 변수 num의 값은 " + num + "입니다.<br>"); // 10
}

globalNum();  // 함수 globalNum()을 호출함.
document.write("함수의 호출이 끝난 뒤 변수 num의 값은 " + num + "입니다."); // 10

또한 전역 변수와 같은 이름의 지역 변수를 선언하면, 해당 블록에서는 해당 이름으로 짗역 변수만 호출할 수 있다.

var num = 10; // 전역 변수 num을 선언함.

function globalNum() {
    var num = 20; // 같은 이름의 지역 변수 num을 선언함.
    document.write("함수 내부에서 변수 num의 값은 " + num + "입니다.<br>"); // 20
}

globalNum(); // 함수 globalNum()을 호출함.
document.write("함수의 호출이 끝난 뒤 변수 num의 값은 " + num + "입니다."); // 10

위의 예제와 같은 경우 해당 블록에서 전역 변수를 호출하려면 전역 변수가 window 객체의 프로퍼티임을 명시하면 된다.

var num = 10; // 전역 변수 num을 선언함.
function globalNum() {
    var num = 20; // 같은 이름의 지역 변수 num을 선언함.
    document.write("함수 내부에서 지역 변수 num의 값은 " + num + "입니다.<br>");
    document.write("함수 내부에서 전역 변수 num의 값은 " + window.num + "입니다.<br>");
}

globalNum(); // 함수 globalNum()을 호출함.

함수의 유효 범위


대부분 프로그래밍 언어에서는 블록 내 정의된 변수를 블록 외부에서는 접근할 수 없다. 블록이란 코드 내에서 중괄호로 둘러싸이는 부분을 가리킨다. 이러한 블록을 기준으로 하는 유효 범위를 블록 단위의 유효 범위라고 한다.

하지만 자바스크립트는 다른 언어와는 달리 함수를 블록 대신 사용한다. 함수는 자신이 정의된 범위 안에서 정의된 모든 변수 및 함수에 접근 가능하다.

‘전역 함수’는 모든 전역 변수와 전역 함수에 접근 가능하다. 반면 다른 함수 내 정의된 ‘내부 함수’는 그 함수의 부모 함수에서 정의된 모든 변수 및 부모 함수가 접근할 수 있는 모든 다른 변수까지 접근 가능하다.

// x, y, name을 전역 변수로 선언함.
var x = 10, y = 20;

// sub()를 전역 함수로 선언함.
function sub() {
    return x - y;     // 전역 변수인 x, y에 접근함.
}

document.write(sub() + "<br>");
// parentFunc()을 전역 함수로 선언함.

function parentFunc() {
    var x = 1, y = 2; // 전역 변수와 같은 이름으로 선언하여 전역 변수의 범위를 제한함.
    function add() {  // add() 함수는 내부 함수로 선언됨.
        return x + y; // 전역 변수가 아닌 지역 변수 x, y에 접근함.
    }
    return add();
}

document.write(parentFunc());

함수 호이스팅(hoisting)

자바스크립트에서 함수의 유효 범위라는 것은 함수 안에서 선언된 모든 변수는 함수 전체에 걸쳐 유효하다는 의미다. 그런데 이 유효 범위의 적용이 변수가 선언되기 전에도 똑같이 적용된다. 이러한 자바 스크립트의 특징을 함수 호이스팅이라고 한다. 즉 자바스크립트 함수 안에 있는 모든 변수의 선언은 함수의 맨 처음으로 이동된 것처럼 동작한다.

var globalNum = 10;     // globalNum을 전역 변수로 선언함.

function printNum() {
    document.write("지역 변수 globalNum 선언 전의 globalNum의 값은 " + globalNum + "입니다.<br>"); // ①
    var globalNum = 20; // globalNum을 지역 변수로 선언함. // ②
    document.write("지역 변수 globalNum 선언 후의 globalNum의 값은 " + globalNum + "입니다.<br>");
}
printNum();

위 코드 printNum()의 첫번째 줄에서 globalNum은 전역 변수를 가르킨다고 생각하기 쉽다. 하지만 실제 코드는 아래와 같이 동작한다.

var globalNum = 10;

function printNum() {
    var globalNum; // 함수 호이스팅에 의해 변수의 선언 부분이 함수의 맨 처음 부분으로 이동됨.
    document.write("지역 변수 globalNum 선언 전의 globalNum의 값은 " + globalNum + "입니다.<br>");
    globalNum = 20;
    document.write("지역 변수 globalNum 선언 후의 globalNum의 값은 " + globalNum + "입니다.<br>");
}
printNum();

globalNum이라는 변수가 선언만되어 있고 아직 초기화만 안된 상태이다. 따라서 이때 globalNum 변수에 접근하면 아직 초기화되지 않은 변수에 접근했으므로 undefined 값을 반환하게 된다.

매개변수와 인수


매개변수

자바스크립트에서는 함수를 정의할 때 매개변수의 타입을 따로 명시하지 않는다. 함수를 호출할 때도 인수로 전달된 값에 대한 어떠한 타입 검사도 하지 않는다.

함수를 호출할 때 함수의 정의보다 적은 수의 인수가 전달되더라도, 다은어어와 달리 오류를 발생시키지 않는다. 이같은 경우 자바스크립트는 전달되지 않은 나머지 매개 변수에 자동으로 undefined 값을 설정한다.

function addNum(x, y, z) { // x, y, z라는 3개의 매개변수를 가지는 함수 addNum()을 정의함.
    return x + y + z;
}

addNum(1, 2, 3); // 인수로 1, 2, 3을 전달하여 함수를 호출함. -> 6
addNum(1, 2);    // 인수로 1, 2을 전달하여 함수를 호출함. -> NaN
addNum(1);       // 인수로 1을 전달하여 함수를 호출함. -> NaN
addNum();        // 인수로 아무것도 전달하지 않고 함수를 호출함. -> NaN

위 예제에서 addNum() 함수를 호출할 때 인수가 세 개보다 적게 전달되면 계산할 수 없다는 의미인 NaN을 반환한다. 그 이유는 전달되지 않은 나머지 값이 자동으로 undefined 값으로 설정되어 산술 연산을 수행할 수 없기 때문이다.

하지만 다음 예제처럼 하면 NaN을 반환하지 않고 전달된 인수만을 가지고 정상적으로 계산하는 함수를 작성할 수 있다.

function addNum(x, y, z) {
    if(x === undefined) // 함수 호출시 x에 해당하는 인수가 전달되지 않은 경우
        x = 0;          // 변수 x의 값을 undefined에서 0으로 변경함.
    if(y === undefined) // 함수 호출시 y에 해당하는 인수가 전달되지 않은 경우
        y = 0;          // 변수 y의 값을 undefined에서 0으로 변경함.
    if(z === undefined) // 함수 호출시 z에 해당하는 인수가 전달되지 않은 경우
        z = 0;          // 변수 z의 값을 undefined에서 0으로 변경함.
    return x + y + z;

}
addNum(1, 2, 3); // 6
addNum(1, 2);    // 3
addNum(1);       // 1
addNum();        // 0

arguments 객체

만약 함수의 정의보다 더 많은 수의 인수가 전달되면 매개변수에 대입되지 못한 인수들은 참조할 방법이 없게 된다. 하지만 arguments 객체를 이용하면 함수로 전달된 인수의 총 개수를 확인하거나 각각의 인수에도 바로 접근 가능하다. arguments 객체는 함수가 호출될 때 전달된 인수를 배열의 형태로 저장하고 있다. 첫번째 인수는 arguments[0]에 저장되며 다음 인수는 arguments[1]에 저장된다. 또한 인수의 총 개수는 arguments 객체의 length 프로퍼티에 저장된다.

다음 예제에서 addNum() 한수는 전달받는 인수의 개수와 상관없이 언제나 정상적인 계산을 수행한다.

function addNum() {
    var sum = 0;                                // 합을 저장할 변수 sum을 선언함.
    for(var i = 0; i < arguments.length; i++) { // 전달받은 인수의 총 수만큼 반복함.
        sum += arguments[i];                    // 전달받은 각각의 인수를 sum에 더함.
    }
    return sum;
}

addNum(1, 2, 3); // 6
addNum(1, 2);    // 3
addNum(1);       // 1
addNum();        // 0
addNum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); // 55

arguments 객체는 배열과 비슷할 뿐, 실제로Array 객체는 아니다. 숫자로 된 인덱스와 length 프로퍼티 만을 가지고 있을 뿐 모든 것을 배열처럼 다룰 수 없다.

디폴트 매개변수와 나머지 매개변수

ECMAScript 6부터 새롭게 정의된 매개변수는 다음과 같다.

  1. 디폴트 매개변수
  2. 나머지 매개변수

디폴트 매개변수

디폴트 매개변수란 함수를 호출할 때 명시된 인수를 전달하지 않았을 경우 사용하게될 기본값을 의미한다.

function mul(a, b = 1) { // 인수가 한 개만 전달되면 나머지 매개변수의 값을 언제나 1로 설정해 줌.
    return a * b;
}

mul(3, 4); // 12
mul(3);    // 3

나머지 매개변수

나머지 매개변수는 생략 접두사(…)를 이용해서 특정 위치의 인수부터 마지막 인수까지를 한번에 지정할 수 있다.

다음 예제는 첫번째 인수에서 두번째 인수부터 마지막 인수까지를 뺸 후 그 결과를 반환하는 예제이다.

function sub() {
    var firstNum = arguments[0];                  // 첫 번째 인수에서
    for(var i = 0; i < arguments.length-1; i++) { // 두 번째부터 마지막 인수까지를
        firstNum -= arguments[i+1];               // 뺌.
    }
    return firstNum;
}

sub(10, 2, 3);    // 10 - 2 - 3 = 5
sub(10, 1, 5, 8); // 10 - 1 - 5 - 8 = -4

하지만 나머지 매개변수를 이용하면 sub() 함수를 좀 더 직관적으로 정의할 수 있다.

// 첫 번째 인수를 변수 firstNum에 저장하고 나머지 인수들은 배열 restArgs에 저장함.
function sub(firstNum, ...restArgs) {
    for(var i = 0; i < restArgs.length; i++) {
        firstNum -= restArgs[i];
    }
    return firstNum;
}

sub(10, 2, 3);    // 10 - 2 - 3 = 5
sub(10, 1, 5, 8); // 10 - 1 - 5 - 8 = -4

나머지 매개변수는 익스플로러, 사파리에서 지원하지 않는다.

미리 정의된 전역 함수


자바스크립트는 사용자의 편의를 위해 다양한 기능의 여러 전역함수를 미리 정의하여 제공한다. 이러한 전역 함수는 자바스크립트의 어떤 타입의 객체에서도 바로 사용 가능하다.

  1. eval()
  2. isFinite()
  3. isNaN()
  4. parseFloat()
  5. parseInt()
  6. decodeURI()
  7. decodeURIComponent()
  8. encodeURI()
  9. encodeURIComponent()
  10. escape()
  11. unescape()
  12. Number()
  13. String()

객체


객체의 개념

객체란 실생활에서 우리가 인식할 수 있는 사물로 이해할 수 있다.


객체의 예

객체(object)

  • 고양이

프로퍼티(property)

  • cat.name = “나비”
  • cat.family = “코리안 숏헤어”
  • cat.age = 0.1
  • cat.weight = 300

메소드(method)

  • cat.mew()
  • cat.eat()
  • cat.sleep()
  • cat.play()

고양이 객체는 모두 위와 같은 프로퍼티를 가지지만 각 프로퍼티의 값은 인스턴스마다 전부 다르다.


자바스크립트 객체

자바스크맅의 기본 타입(data type)은 객체(object)이다.

프로퍼티의 값으로 함수가 올 수도 있는데 이러한 프로퍼티를 메소드라고 한다.

var cat = "나비"; // 일반적인 변수의 선언
// 객체도 많은 값을 가지는 변수의 하나임.
var kitty = { name: "나비", family: "코리안 숏 헤어", age: 1, weight: 0.1 };
cat          // 나비
kitty.name   // 나비

객체의 프로퍼티 참조

자바스크립트에서 객체의 프로퍼티를 참조하는 방법은 다음과 같다.

객체이름.프로퍼티이름
또는
객체이름["프로퍼티이름"]
var person = {
    name: "홍길동",      // 이름 프로퍼티를 정의함.
    birthday: "030219",  // 생년월일 프로퍼티를 정의함.
    pId: "1234567",      // 개인 id 프로퍼티를 정의함.
    fullId: function() { // 생년월일과 개인 id를 합쳐서 주민등록번호를 반환함.
        return this.birthday + this.pId;
    }
};

person.name    // 홍길동
person["name"] // 홍길동

객체의 메소드 참조

자바스크립트에서 객체의 메소드를 참조하는 방법은 다음과 같다.

var person = {
    name: "홍길동",
    birthday: "030219",
    pId: "1234567",
    fullId: function() {
        return this.birthday + this.pId;
    }
};

person.fullId() // 0302191234567
person.fullId;  // function () { return this.birthday + this.pId; }

메소드를 참조할 때 메소드 이름 뒤에 괄호를 붙이지 않으면 메소드가 아닌 프로퍼티 그 자체를 참조하게된다. 따라서 괄호를 사용하지 않고 프로퍼티 그 자체를 참조할 경우 해당 메소드의 정의 그 자체가 반환된다.


객체의 생성

자바스크립트에서 객체를 생성하는 방법은 다음과 같다.

  1. 리터럴 표기를 이용한 방법
  2. 생성자 함수를 이용한 방법
  3. Object.create() 메소드를 이용한 방법

위와 같은 방법으로 생성되어 메모리에 대입된 객체를 인스턴스(instance)라고 한다.


리터럴 표기를 이용한 객체의 생성

자바스크립트에서 객체를 생성하는 가장 쉬운 방법은 리터럴 표기를 이용하는 방법니다.

var kitty = {
    name: "나비",
    family: "코리안 숏 헤어",
    age: 1,
    weight: 0.1
};
document.write("우리 집 새끼 고양이의 이름은 " + kitty.name + "이고, 종은 " + kitty.family + "입니다.");

생성자를 이용한 객체의 생성

new 연산자를 사용해서 객체를 생성하고 초기화할 수 있다. 이때 사용되는 메소드를 생성자(constructor)라고 하며 이 메소드는 새롭게 생성되는 객체를 초기화하는 역할을 한다. 자바스크립트는 원시 타입을 위한 생성자를 미리 정의해서 제공한다.

var day = new Date(); // new 연산자를 사용하여 Date 타입의 객체를 생성함
document.write("올해는 " + day.getFullYear() + "년입니다.");

var yellowKitty = new kitty()
document.write("우리 집 새끼 고양이의 이름은 " + yellowKitty.name + "이고, 종은 " + yellowKitty.family + "입니다.");

Object.create() 메소드를 이용한 객체의 생성

Object.create() 메소드를 이용하여 객체를 생성할 수도 있다. 해당 메소드는 지정된 프로토타입(prototype) 객체와 프로퍼티를 가지고 새로운 객체를 만들어준다. 따라서 이 메소드를 이용하면 사용자가 프로토타입 객체를 직접 명시할 수 있으므로 상당히 유용하게 사용된다.

Object.create(프로토타입객체[, 새로운객체의프로퍼티1, 새로운객체의프로퍼티2, ...]);

Object.create() 메소드의 첫 번째 인수로는 프로토타입으로 사용할 객체를 전달한다. 두 번째 인수로는 새로운 객체의 추가할 프로퍼티 정보를 전달한다.

var obj = Object.create(null, {             // null 프로토타입을 사용하여 새로운 객체를 만들고
    x: { value: 100, enumerable: true },    // x좌표를 나타내는 열거할 수 있는 프로퍼티와
    y: { value: 200, enumerable: true }     // y좌표를 나타내는 열거할 수 있는 프로퍼티를 추가함.
});

obj.x;                      // x좌표
obj.y;                      // y좌표 
Object.getPrototypeOf(obj); // 객체의 프로토타입을 반환해 줌.

프로토타입 (중요!)

상속(Inheritance)

상속이란 새로운 클래스에서 기존 클래스의 모든 프로퍼티와 메소드를 사용할 수 있는 것을 의미한다.

상속을 통해 기존 클래스를 수정하여 재사용하거나 클래스간의 종속 관계를 형성하여 객체의 관계를 조직화할 수 있는 장점이 있다. 이러한 상속은 추상화, 캡슐화와 더불어 객체 지향 프로그래밍을 구성하는 중요한 특징 중 하나다.

하지만 C#, C++과 같은 기반의 책체 지향 언어와는 달리 자바스크립트는 프로타입 기반의 객체 지향 언어이다. 프로타입 기반이기 때문에 상속의 개념이 클래스 기반의 객체 지향 언어와는 약간 다른다.


프로토타입

모든 객체는 프로토타입이라는 객체를 가지고 있으며 그들의 프로타입으로부터 프로퍼티와 메소드를 상속받는다. 이처럼 자바스크립트의 모든 객체는 최소한 하나 이상의 다른 객체로부터 상속을 받으며 이때 상속되는 정보를 제공하는 객체를 프로토타입이라고 한다.


프로토타입 체인(prototype chain)

자바스크립트에서는 객체 이니셜라이저를 사용해 생성된 같은 타입의 객체들은 모두 같은 프로토타입을 가진다. 또한 new 연산자를 사용해 생성한 객체는 생성자의 프로토타입을 자신의 프로토타입으로 상속받는다.

var obj = new Object(); // 이 객체의 프로토타입은 Object.prototype입니다.
var arr = new Array();  // 이 객체의 프로토타입은 Array.prototype입니다.
var date = new Date();  // 이 객체의 프로토타입은 Date.prototype입니다.

하지만 Object.prototype 객체는 어떠한 프로토타입도 가지지 않으며 아무런 프로퍼티도 상속받지 않는다. 또한 자바스크립트에 내장된 모든 생성자나 사용자 정의 생성자는 바로 이 객체를 프로토타입으로 가진다.

https://hanamon.kr/javascript-프로토타입과-프로토타입체인/


프로토타입의 생성

프로토타입을 생성하는 가장 기본적인 방법은 객체 생성자 함수를 작성하는 것이다. 생성자 함수를 작성하고 new 연산자를 사용해 객체를 생성하면 같은 프로토타입을 가지는 객체들을 생성할 수 있다.

function Dog(color, name, age) { // 개에 관한 생성자 함수를 작성함.
    this.color = color;          // 색에 관한 프로퍼티
    this.name = name;            // 이름에 관한 프로퍼티
    this.age = age;              // 나이에 관한 프로퍼티
}

var myDog = new Dog("흰색", "마루", 1); // 이 객체는 Dog라는 프로토타입을 가짐.
document.write("우리 집 강아지는 " + myDog.name + "라는 이름의 " + myDog.color + " 털이 매력적인 강아지입니다.");

객체 생성자 생성시 관례상 이름의 첫 문자만 대문자로 작성한다.


객체에 프로퍼티 및 메소드 추가

이미 생성된 객체에 새로운 프로퍼티나 메소드를 추가하는 방법은 다음과 같다.

function Dog(color, name, age) {
    this.color = color;
    this.name = name;
    this.age = age;
}

var myDog = new Dog("흰색", "마루", 1);
myDog.family = "시베리안 허스키"; // 품종에 관한 프로퍼티를 추가함.
myDog.breed = function() {        // 털색을 포함한 품종을 반환해 주는 메소드를 추가함.
    return this.color + " " + this.family;
}
document.write("우리 집 강아지는 " + myDog.breed() + "입니다.");

추가된 family, breed는 오직 myDog 인스턴스에만 추가된다.


프로토타입에 프로퍼티 및 메소드 추가

프로토타입에 새로운 프로퍼티나 메소드를 추가하는것은 객체에 추가할 때와는 다른 방법을 사용해야 한다.

프로토타입의 경우에는 생성자 함수에 직접 추가해야만 이후에 생성되는 모든 다른 객체에도 적용할 수 있다.

function Dog(color, name, age) {
    this.color = color;
    this.name = name;
    this.age = age;
    this.family = "시베리안 허스키"; // 프로토타입에 프로퍼티를 추가할 때에는 기본값을 가지게 할 수 있음.
    this.breed = function() {
        return this.color + " " + this.family;
    };
}

var myDog = new Dog("흰색", "마루", 1);
var hisDog = new Dog("갈색", "콩이", 3);

document.write("우리 집 강아지는 " + myDog.family + "이고, 친구네 집 강아지도 " + hisDog.family + "입니다.");

prototype 프로퍼티

prototype 프로퍼티를 이용하면 현재 존재하고 있는 프로타입에 새로운 프로퍼티나 메소드를 손쉽게 추가할 수 있다.

function Dog(color, name, age) {
    this.color = color;
    this.name = name;
    this.age = age;
}

// 현재 존재하고 있는 Dog 프로토타입에 family 프로퍼티를 추가함.
Dog.prototype.family = "시베리안 허스키";

// 현재 존재하고 있는 Dog 프로토타입에 breed 메소드를 추가함.
Dog.prototype.breed = function() {
    return this.color + " " + this.family;
};

var myDog = new Dog("흰색", "마루", 1);
var hisDog = new Dog("갈색", "콩이", 3);

document.write("우리 집 강아지는 " + myDog.family + "이고, 친구네 집 강아지도 " + hisDog.family + "입니다.");
document.write("우리 집 강아지의 품종은 " + myDog.breed() + "입니다.<br>");
document.write("친구네 집 강아지의 품종은 " + hisDog.breed() + "입니다.");

직접 생성한 프로토타입은 위와 같이 새로운 프로퍼티나 메소드를 마음껏 추가 혹은 삭제 가능하다. 물론 자바스크립트 표준 객체의 프로토타입도 임의로 수정할 수 있으나 심각한 오류가 발생할 가능성이 있다. 따라서 자바스크립트 표준 객체의 프로토타입은 수정해서는 안된다.

객체 다루기

this 키워드

메소드 내부에서 사용된 this 키워드는 해당 메소드를 포함하고있는 객체를 가리킨다. 또한 객체 내부에서 사용된 this 키워드는 객체 그 자신을 가리킨다. 이러한 this는 변수가 아닌 키워드이므로 사용자가 임의로 가리키는 값을 바꿀 수 없다.


객체 프로퍼티 삭제

function Dog(color, name, age) {
    this.color = color;
    this.name = name;
    this.age = age;
}

var myDog = new Dog("흰색", "마루", 1);
delete myDog.age; // age 프로퍼티를 삭제함.
// age 프로퍼티가 삭제되었기 때문에 undefined를 출력함.
document.write("우리집 강아지의 나이는 " + myDog.age + "입니다.");

객체 프로퍼티 순회

for / in 문을 사용하여 객체의 모든 프로퍼티를 순회할 수 있다.

for / in 문은 객체의 모든 열거 가능한 프로퍼티(enumerable properties)를 손쉽게 순회할 수 있도록 도와준다.

객체의 프로퍼티를 순회하는 방법으로는 for / in 문 이외에도 다음과 같은 메소드를 사용할 수 있다.

  1. Object.keys()
  2. Object.getOwnPropertyNames()

Object.keys() 메소드는 해당 객체가 가진 고유 프로퍼티 중에서 열거할 수 있는 프로퍼티의 이름을 배열에 담아 반환한다. Object.getOwnPropertyNames() 메소드는 해당 객체가 가진 모든 고유 프로퍼티의 이름을 배열에 담아 반환한다.

function Dog(color, name, age) {
    this.color = color;
    this.name = name;
    this.age = age;
}

var myDog = new Dog("흰색", "마루", 1);

// color 프로퍼티의 enumerable 속성을 false로 설정함.
Object.defineProperty(myDog, 'color', {enumerable : false} );

// 객체가 가진 고유 프로퍼티 중에서 열거할 수 있는 프로퍼티 이름을 배열에 담아 반환함.
document.write(Object.keys(myDog) + "<br>");       // name, age

// 객체가 가진 모든 고유 프로퍼티의 이름을 배열에 담아 반환함.
document.write(Object.getOwnPropertyNames(myDog)); // color, name, age

객체간의 비교

자바스크립트에서 별개의 두 객체는 프로퍼티 값이 모두 같아도 절대로 같다고 할 수 없다.

function Dog(color, name, age) {
    this.color = color;
    this.name = name;
    this.age = age;
}

var myDog = new Dog("흰색", "마루", 1);
var hisDog = new Dog("흰색", "마루", 1);      // 모든 프로퍼티의 값이 모두 같은 객체를 생성함.
document.write((myDog == hisDog) + "<br>");   // false
document.write((myDog === hisDog) + "<br>");  // false

 
var herDog = hisDog;                          // hisDog 객체를 변수 herDog에 대입함.
document.write((hisDog == herDog) + "<br>");  // true
document.write((hisDog === herDog) + "<br>"); // true

위 예제에서 myDog와 hisDog 객체는 가지고 있는 프로퍼티 값이 모두 같지만 두 객체는 별개의 객체이므로 동등(==) 연산자와 일치(===) 연상자로 비교해도 모두 false를 반환한다. 위 예제에서는 변수 herDog에 hisDog를 대입하는데 이렇게 객체를 대입한 변수를 “객체 레퍼런스”라고 하며 이제부터 변수 herDog는 hisDog 객체를 가리키게 된다. 객체 레퍼런스는 객체 자체를 저장하는 것이 아니라 객체가 위치한 주소를 저장하는 것이다. 따라서 herDog와 hisDog는 동등 연산자와 일치 연산자로 비교하면 모두 true를 반환하게 된다.


객체 프로퍼티와 메소드

객체 프로퍼티

모든 자바스크립트 객체는 Object 객체와 Object.prototype 객체의 모든 프로퍼티를 상속받는다.

prototype 프로퍼티를 이용하면 현재 존재하는 프로토타입에 새로운 프로퍼티나 메소드를 손쉽게 추가할 수있다.


객체 메소드(method)

Object와 Object.prototype 객체의 모든 프로퍼티와 메소드를 상속받고 자주사용되는 대표적인 객체 메소드는 다음과 같다.

  1. hasOwnProperty()

    • 특정 프로퍼티가 해당 객체에 존재하는지 검사함
    function Dog(color, name, age, family) {
        this.color = color;
        this.name = name;
        this.age = age;
        this.family = family;
        this.breed = function() {
            return this.color + " " + this.family;
        }
    }
    
    var myDog = new Dog("검정색", "곰", 3, "불독");
    myDog.hasOwnProperty("color"); // true
    myDog.hasOwnProperty("breed"); // true
    myDog.hasOwnProperty("class"); // 상속받은 프로퍼티이므로, false를 반환함.
  2. propertyIsEnumerable()

    • 특정 프로퍼티가 해당 객체에 존재하고 열거할 수 있는 프로퍼티인지를 검사한다.
    function Dog(color, name, age) {
        this.color = color;
        this.name = name;
        this.age = age;
    }
    
    var myDog = new Dog("흰색", "마루", 1);
    
    // color 프로퍼티의 enumerable 속성을 false로 설정함.
    Object.defineProperty(myDog, 'color', { enumerable : false} );
     
    document.write(myDog.propertyIsEnumerable("color") + "<br>"); // false
    document.write(myDog.propertyIsEnumerable("name") + "<br>");  // true
    document.write(myDog.propertyIsEnumerable("age"));            // true

    열거 가능 프로퍼티란 내부적으로 enumerable 플래그가 true로 설정된 프로퍼티를 의미한다. 이러한 프로퍼티들은 for / in 문으로 접근할 수 있게된다.

  3. isPrototypeOf()

    • 특정 객체의 프로토타입 체인에 현재 객체가 존재하는지 검사
    var day = new Date(); // Date 객체를 생성함.
    // 객체 day의 프로토타입이 Date.prototype인지를 검사함.
    document.write(Date.prototype.isPrototypeOf(day));          // true
    document.write(Date.prototype.isPrototypeOf(new String())); // false
  4. isExtensible()

    • 객체에 새로운 프로퍼티를 추가할 수 있는지 여부를 반환한다.
    var day = new Date(); // Date 객체를 생성함.
    // 객체 day에 새로운 프로퍼티를 추가할 수 있는지 검사함.
    document.write(Object.isExtensible(day) + "<br>"); // true
    
    // 해당 객체에 새로운 프로퍼티를 추가할 수 없도록 설정함.
    var myDay = Object.preventExtensions(day);
    document.write(Object.isExtensible(day));          // false
  5. toString()

    • 호출한 객체의 값을 문자열로 반환한다.
    var arr = [10, "문자열", true]; // 배열
    var bool = false;               // 불리언
    function func() { return 0; }   // 함수
    
    arr.toString();  // 10,문자열,true
    bool.toString(); // false
    func.toString(); // 함수의 소스 코드가 전부 문자열로 반환됨.
  6. valueOf()

    • 특정 객체의 원시 타입의 값을 반환한다. 자바스크립트에서는 원시 타입의 값이 기대되는 곳에 객체가 사용되면 내부적으로 이 메소드를 호출하여 처리한다. 만약 어떤 객체가 원시 타입의 값을 가지고 있지 않다면 이 메소드는 객체 자신을 반환한다.
    function func(n) {
        this.number = n;
    }
    
    myFunc = new func(4);
    document.write(myFunc + 5); // ① : [object Object]5
    
    func.prototype.valueOf = function() { // valueOf() 메소드를 정의함.
        return this.number;
    }
    
    document.write(myFunc + 5); // ② : 9

    예제 1번에서는 number 타입의 값을 기대하는 곳에 myFunc 객체가 사용된다. 따라서 자바스크립트 내부적으로 해당 객체의 valueOf() 메소드를 호출한다. 하지만 이 객체의 valueOf() 메소드는 아직 정의되지 않았으므로 해당 객체는 자신을 반환한다. 따라서 산술 연산이 아닌 문자열 결합 연산이 수행된다.

    그후에 예제에서는 prototype 프로퍼티를 이용하여 valueOf() 메소드를 정의한다. 따라서 2번 예제에서는 내부적으로 호출된 valueOf() 메소드가 해당 객체의 number 프로퍼티 값을 반환한다. 따라서 정상적으로 산술 연산이 수행된다.

  7. getter와 setter 메소드의 정의

    • getter와 setter 메소드로 정의된 프로퍼티는 단순한 값을 지닌 데이터 프로퍼티와는 달리 접근자 프로퍼티라고 부른다. getter 메소드는 특정 프로퍼티의 값을 받아오기 위한 메소드이다. 자바스크립트는 객체의 프로퍼티 값에 접근할 때 getter 메소드에 아무런 인수를 전달하지 않고 호출한다. setter 메소드는 특정 프로퍼티의 값을 설정하기 위한 메소드이다. 자바스크립트는 객체의 프로퍼티 값을 변경할 때 setter메소드에 대입하고자 하는 값을 인수로 전달하여 호출한다.
    var gildong = { age: 18 };
    document.write(gildong.age + "<br>"); // 18
    
    Object.defineProperty(gildong, "americanAge", { get: function() { return this.age - 1; } });
    document.write(gildong.americanAge); // 17
    • 위 예제에서는 gildong 객체에 americanAge라는 프로퍼티를 추가할 때 get 키워드를 사용하여 getter 메소드를 정의하고 있다. 따라서 해당 프로퍼티를 참조하려고 할 때는 내부적으로 미리 정의한 getter 메소드가 자동으로 호출될 것이다.
    • 다음 예제는 setter 메소드를 정의하는 예제이다.
    var gildong = { age: 18 };
    gildong.age = 20;
    document.write(gildong.age + "<br>"); // 20
    
    Object.defineProperty(gildong, "changeAge", { set: function(n) { this.age = this.age - n; } });
    gildong.changeAge = 5;
    document.write(gildong.age); // 15
    • gildong 객체에 changAge라는 프로퍼티를 추가할 때 set 키워드를 사용하여 setter 메소드를 정의하고 해당 프로퍼티의 값을 변경하려고 할 때 내부적으로 미리 정의한 setter 메소드가 자동으로 호출된다.

표준 객체

전역 객체

전역 객체와 래퍼 객체

전역 객체란 자바스크립트에 미리 정의된 객체로 전역 프로퍼티나 전역 함수를 담는 공간의 역할을 한다. 전역 객체 그 자체는 전역 범위에서 this 연산자를 통해 접근할 수 있다.

자바스크립트에서 모든 객체는 전역 객체의 프로퍼티가 된다. 웹 브라우저가 새로운 페이지를 로드하면 자바스크립트는 새로운 전역 개체를 만들고 해당 프로퍼티들을 초기화 한다.


래퍼 객체(wrapper object)

var str = "문자열";   // 문자열 생성
var len = str.length; // 문자열 프로퍼티인 length 사용

위 코드에서 생성한 문자열 리터럴 str은 객체가 아닌데도 length 프로퍼티를 사용할 수 있다. 프로그램이 문자열 리터럴 str의 프로퍼티를 참조하려고 하면 자바스크립트는 new String(str)을 호출한것처럼 문자열 리터럴을 객체로 자동 변환해주기 때문이다.

이렇게 생성된 임시 객체는 String 객체의 메소드를 상속받아 프로퍼티를 참조하는데 사용된다. 이후 프로퍼티의 참조가 끝나면 사용된 임시 객체는 자동으로 삭제된다. 이렇게 숫자, 문자열, 불리언 등 원시 타입의 프로퍼티에 접근하려고 할 때 생성되는 임시 객체를 래퍼 객체라고 한다.

var str = "문자열";           // 문자열 리터럴 생성
var strObj = new String(str); // 문자열 객체 생성
str.length;                   // 리터럴 값은 내부적으로 래퍼 객체를 생성한 후에 length 프로퍼티를 참조함.
str == strObj;                // 동등 연산자는 리터럴 값과 해당 래퍼 객체를 동일하게 봄.
str === strObj;               // 일치 연산자는 리터럴 값과 해당 래퍼 객체를 구별함.
typeof str;                   // string 타입
typeof strObj;                // object 타입

https://includestdio.tistory.com/26


표준 객체

자바스크립트에서 표준 객체는 다른 객체의 기초가 되는 핵심적인 객체이다. 자주 사용되는 대표적인 자바스크립트 표준 객체는 다음과 같다.

  1. Number
  2. Math
  3. Date
  4. String
  5. Array

문서 객체 모델

DOM의 개념

문서 객체 모델(DOM)이란?

XML이나 HTML 문서에 접근하기 위한 인터페이스로 이 객체 모델은 문서 내의 모든 요소를 정의하고 각 요소에 접근하는 방법을 제공한다. 이러한 DOM은 W3C의 표준 객체 모델이며 다음과 같은 계층 구조로 표현된다.

자바스크립트는 이러한 객체 모델을 이용하여 다음과 같은 작업을 할 수 있다.

  • 새로운 HTML 요소나 속성을 추가할 수 있다.
  • 존재하는 HTML요소나 속성을 제거할 수 있다
  • HTML 문서의 모든 HTML 요소, 속성, CSS를 변경할 수 있다
  • HTML 문서의 모든 HTML 이벤트를 추가하거나 반응할 수 있다.

DOM의 종류

W3C DOM 표준은 세 가지 모델로 구분된다.

  1. Core DOM : 무든 문서 타입을 위한 DOM 모델
  2. HTML DOM : HTML 문서를 위한 DOM 모델
  3. XML DOM : XML 문서를 위한 DOM 모델

Document 객체

Document 객체는 웹페이지 그 자체를 의미한다. 웹 페이지에 존재하는 HTML 요소에 접근하고자 할때는 반드시 Document 객체부터 시작해야 한다.


Document 메소드

Document 객체는 HTML 요소와 관련된 작업을 도와주는 다양한 메소드를 제공한다.

  1. HTML 요소의 선택

    메소드설명
    document.getElementsByTagName(태그이름)해당 태그 이름의 요소를 모두 선택함.
    document.getElementById(아이디)해당 아이디의 요소를 선택함.
    document.getElementsByClassName(클래스이름)해당 클래스에 속한 요소를 모두 선택함.
    document.getElementsByName(name속성값)해당 name 속성값을 가지는 요소를 모두 선택함.
    document.querySelectorAll(선택자)해당 선택자로 선택되는 요소를 모두 선택함.
  2. HTML 요소의 생성

    메소드설명
    document.createElement(HTML요소)지정된 HTML 요소를 생성함.
    document.write(텍스트)HTML 출력 스트림을 통해 텍스트를 출력함.
  3. HTML 이벤트 핸들러 추가
    HTML DOM Level 1은 1998년에 정의되어 HTML5에서도 계속 사용되고 있다. 그 후 2004년에는 HTML DOM Level 3가 새롭게 정의되어 Level 1과 같이 사용되고 있다. 이러한 HTML DOM 에서 제공하는 객체 집합을 이용하면 HTML 객체를 손쉽게 선택할 수 있다.

    | 객체 집합 | 설명 |
    | --- | --- |
    | document.anchors | name 속성을 가지는 <a>요소를 모두 반환함. |
    | document.applets | applet 요소를 모두 반환함. (HTML5에서 제외됨) |
    | document.body | <body>요소를 반환함. |
    | document.cookie | HTML 문서의 쿠키(cookie)를 반환함. |
    | document.domain | HTML 문서가 위치한 서버의 도메인 네임(domain name)을 반환함. |
    | document.forms | <form>요소를 모두 반환함. |
    | document.images | <img>요소를 모두 반환함. |
    | document.links | href 속성을 가지는 <area>요소와 <a>요소를 모두 반환함. |
    | document.referrer | 링크(linking)되어 있는 문서의 URI를 반환함. |
    | document.title | <title>요소를 반환함. |
    | document.URL | HTML 문서의 완전한 URL 주소를 반환함. |
    | document.baseURI | HTML 문서의 절대 URI(absolute base URI)를 반환함. |
    | document.doctype | HTML 문서의 문서 타입(doctype)을 반환함. |
    | document.documentElement | <html>요소를 반환함. |
    | document.documentMode | 웹 브라우저가 사용하고 있는 모드를 반환함. |
    | document.documentURI | HTML 문서의 URI를 반환함. |
    | document.domConfig | HTML DOM 설정을 반환함. (더는 사용하지 않음) |
    | document.embeds | <embed>요소를 모두 반환함. |
    | document.head | <head>요소를 반환함. |
    | document.implementation | HTML DOM 구현(implementation)을 반환함. |
    | document.inputEncoding | HTML 문서의 문자 인코딩(character set) 형식을 반환함. |
    | document.lastModified | HTML 문서의 마지막 갱신 날짜 및 시간을 반환함 |
    | document.readyState | HTML 문서의 로딩 상태(loading status)를 반환함. |
    | document.scripts | <script>요소를 모두 반환함. |
    | document.strictErrorChecking | 오류의 강제 검사 여부를 반환함. |

DOM 요소


DOM 요소의 선택

HTML 요소를 다루기 위해서 우선 해당 요소를 선택해야 함

자바스크립트에서 특정 HTML 요소를 선택하는 방법은 다음과 같다

  1. HTML 태그(tag name) 이름을 이용한 선택
  2. 아이디(id)를 이용한 선택
  3. 클래스(class)를 이용한 선택
  4. name 속성(attribute)을 이용한 선택
  5. css 선택자(seletor)를 이용한 선택
  6. HTML 객체 집합(object collection)을 이용한 선택

HTML 태그 이름을 이용한 선택

getElementByTagName() 메소드는 HTML 태그 이름을 이용하여 HTML 요소를 선택한다.

var selectedItem = document.getElementsByTagName("li"); // 모든 <li> 요소를 선택함.

for (var i = 0; i < selectedItem.length; i++) {
    selectedItem.item(i).style.color = "red"; // 선택된 모든 요소의 텍스트 색상을 변경함.
}

아이디를 이용한 선택

getElementById() 메소드는 아이디를 이용하여 HTML 요소를 선택한다.

var selectedItem = document.getElementById("even"); // 아이디가 "even"인 요소를 선택함.
selectedItem.style.color = "red"; // 선택된 요소의 텍스트 색상을 변경함.

자바스크립트에서 아이디를 이용한 선택은 해당 아이디를 가지고 있는 요소 중에서 첫번째 요소 단 하나만을 선택한다. 따라서 여러 요소를 선택하고 싶을 때는 태그 이름이나 클래스와 같은 다른 방법을 사용해야 한다.


클래스를 이용한 선택

getElementsByClassName() 메서드는 클래스 이름을 이용하여 HTML 요소를 선택한다.

var selectedItem = document.getElementsByClassName("odd"); // 클래스가 "odd"인 모든 요소를 선택함.

for (var i = 0; i < selectedItem.length; i++) {
    selectedItem.item(i).style.color = "red"; // 선택된 모든 요소의 텍스트 색상을 변경함.
}

name 속성을 이용한 선택

getElementByName() 메소드는 HTML 요소의 name 속성을 이용하여 HTML 요소를 선택한다.

var selectedItem = document.getElementsByName("first"); // name 속성값이 "first"인 모든 요소를 선택함.

for (var i = 0; i < selectedItem.length; i++) {
    selectedItem.item(i).style.color = "red"; // 선택된 모든 요소의 텍스트 색상을 변경함.
}

CSS 선택자(selector)를 이용한 선택

querySelectorAll() 메소드는 CSS 선택자(아이디, 클래스, 속성, 속성값 등)를 이용해서 HTML 요소를 선택다.

var selectedItem = document.querySelectorAll("li.odd"); // 클래스가 "odd"인 요소 중에서 <li> 요소만을 선택함.

for (var i = 0; i < selectedItem.length; i++) {
    selectedItem.item(i).style.color = "red"; // 선택된 모든 요소의 텍스트 색상을 변경함.
}

HTML 객체 집합(object collection)을 이용한 선택

HTML DOM에서 제공하는 객체집합을 이용하여 HTML 요소를 선택

var title = document.title; // <title> 요소를 선택함.
document.write(title);

DOM 요소의 내용 변경

HTML DOM을 이용하면 HTML 요소의 내용(Content)이나 속성값 등을 손쉽게 변경 가능하다.
HTML 요소의 내용을 변경하는 가장 쉬운 방법은 innerHTML 프로퍼티를 이용하는 것이다.

var str = document.getElementById("text");
str.innerHTML = "이 문장으로 바뀌었습니다!";

HTML 요소의 속성 이름을 이용하면 속성값도 변경 가능하다.

var link = document.getElementById("link");          // 아이디가 "link"인 요소를 선택함.
link.href = "/javascript/intro"; // 해당 요소의 href 속성값을 변경함.
link.innerHTML = "자바스크립트 수업 바로 가기!";     // 해당 요소의 내용을 변경함.

DOM 요소의 스타일 변경

HTML DOM을 이용하면 HTML 요소의 스타일도 손쉽게 변경 가능하다.
style 프로퍼티를 이용하여 HTML 요소에 css 스타일을 적용한다.

var str = document.getElementById("text");                 // 아이디가 "text"인 요소를 선택함.
function changeRedColor() { str.style.color = "red"; }     // 해당 요소의 글자색을 빨간색으로 변경함.
function changeBlackColor() { str.style.color = "black"; } // 해당 요소의 글자색을 검정색으로 변경함.

노드


노드(node)

HTML DOM은 노드라고 불리는 계층적 단위에 정보를 저장하고 있으며 이러한 노드들을 정의하고 그들 사이의 관계를 설명해주는 역할을 한다.

HTML 문서의 정보는 노드 트리라고 불리는 계층적 구조에 저장된다. 이러한 노드 트리는 노드들의 집합이며 노드간의 관계를 보여준다.

노드 트리는 최상위 레벨인 루트 노드로부터 시작해서 가장낮은 레벨인 텍스트 노드까지 뻐더어 내려간다. 자바스크립트에서는 HTML DOM을 이용해서 노드 트리에 포함된 모든 노드에 접근 가능하다.


노드의 종류

W3C HTML DOM 표준에 따르면 HTML 문서의 모든 것은 노드이다.
HTML 문서를 구성하는 대표적인 노드의 종류는 다음과 같다.

노드설명
문서노드(docuement node)HTML 문서 전체를 나타내는 노드
요소 노드(element node)모든 HTML 요소는 요소 노드이며 속성 노드를 가질수 있는 유일한 노드
속성 노드(attribute node)모든 HTML 요소의 속성은 속성 노드이며 요소 노드에 관한 정보를 자지고 있다. 그러나 해당 요수 노드의 자식 노드(child node)에는 포함되지 않음
텍스트 노드(text node)HTML 문서의 모든 텍스트는 텍스트 노드이다
주석 노드(comment node)HTML 문서의 모든 주석은 주석 노드이다

노드 간의 관계

노드 트리의 모든 노드는 서로 계층적 관계를 맺고 있다.

노드 트리 가장 상위에는 단 하나의 루트 노드가 존재한다.
루트 노드를 제외한 모든 노드는 단 하나의 부모 노드만을 가진다.
모든 요소 노드는 자식 노드(child node)를 가질 수 있다.

형제 노드(sibling node)란 같은 부모 노드를 가지는 모든 노드를 가리킨다.
조상 노드란 부모 노드를 포함해 계층적으로 현재 노드보다 상위에 존재하는 모든 노드를 가리킨다.

자손 노드란 자식 노드를 포함해 계층적으로 현재 노드보다 하위에 존재하는 모든 노드를 가리킨다.

노드로의 접근

HTML 문서에서 HTML DOM 노드에 접근하는 방법은 다음과 같다.
1. getElementsByTagName() 메소드를 이용하는 방법
2. Node간의 관계를 이용하여 접근하는 방법


getElementsByTagName() 메소드 이용 방법

특정 태그 이름을 가지는 모든 요소를 노드 리스트의 형태로 반환한다.
따라서 이 메소드가 반환하는 노드 리스트를 이용하면 원하는 노드에 접근할 수 있다.


노드간의 관계를 이용하여 접근하는 방법

HTML DOM에서 노드 간의 관계는 다음과 같은 프로퍼티로 정의된다.

1. parentNode : 부모 노드
2. childNodes : 자식 노드 리스트
3. firstChild : 첫 번째 자식 노드
4. lastChild : 마지막 자식 노드
5. nextSibling : 다음 형제 노드
6. previousSibling : 이전 형제 노드

위와 같은 프로퍼티를 이용해서 원하는 노드에 손쉽게 접근할 수 있다.


노드에 대한 정보

노드에 대한 정보는 다음과 같은 프로퍼티를 통해 접근 할 수 있다.
1. nodeName
2. nodeValue
3. nodeType

이 프로퍼티들은 특별히 다른 인터페이스를 이용하지않아도 해당 노드 정보에 직접 접근 가능한 방법을 제공한다.


NodeName

nodeName 프로퍼티는 노드 고유 이름을 저장하므로 수정할 수 없는 읽기 전용 프로퍼티이다.
요소 노드의 nodeName프로퍼티는 언제나 해당 HTML 요소의 태그 이름을 대문자로 저장한다.

노드프로퍼티 값
문서 노드#document
요소 노드태그 이름(영문자로 대문자)
속성 노드속성 이름
텍스트 노드#text

<!DOCTYPE html>
<html lang="ko">

<head>
	<meta charset="UTF-8">
	<title>JavaScript Node Access</title>
</head>

<body>

	<h1>nodeName 프로퍼티</h1>
	<p id="document"></p>
	<p id="html"></p>
	
	<script>
		// HTML 문서의 모든 자식 노드 중에서 두 번째 노드의 이름을 선택함.
		document.getElementById("document").innerHTML = document.childNodes[1].nodeName;			// HTML
		
		// html 노드의 모든 자식 노드 중에서 첫 번째 노드의 이름을 선택함.
		document.getElementById("html").innerHTML = document.childNodes[1].childNodes[0].nodeName;	// HEAD
	</script>
	
</body>

</html>

nodeValue

nodeValue 프로퍼티는 노드의 값을 저장한다.

노드프로퍼티 값
요소 노드undefined
속성 노드해당 속성의 속성값
텍스트 노드해당 텍스트 문자열
<!DOCTYPE html>
<html lang="ko">

<head>
	<meta charset="UTF-8">
	<title>JavaScript Node Access</title>
</head>

<body>

	<h1 id="heading">nodeValue 프로퍼티</h1>
	<p id="text1">텍스트</p>
	<p id="text2">텍스트</p>
	
	<script>
		// 아이디가 "heading"인 요소의 첫 번째 자식 노드의 노드값을 선택함.
		var headingText = document.getElementById("heading").firstChild.nodeValue;
		
		document.getElementById("text1").innerHTML = headingText;
		document.getElementById("text2").firstChild.nodeValue = headingText;
	</script>
	
</body>

</html>

브라우저 객체 모델

Window 객체


브라우저 객체 모델(BOM)이란?

자바스크립트를 이용하면 브라우저의 정보에 접근하거나 여러 기능을 제어할 수 있다. 이때 사용 할 수 있는 객체 모델이 브라우저 객체 모델(BOM, Brawser Object Model)이다.

브라우저 객체 모델은 문서 객체 모델과는 달리 W3C 표준 객체 모델은 아니다.
하지만 이 모델은 자바스크립트가 브라우저의 기능적인 요소들을 직접 제어하고 관리할 방법을 제공해 준다. 자바스크립트에서는 이러한 BOM 객체들을 전역 객체로 사용할 수 있다.


Window 객체

Windows 객체는 브라우저의 창을 나타내는 객체로 대부분의 웹 브라우저에서 지원한다.

자바스크립트의 모든 객체, 전역 함수, 전역 변수들은 자동으로 window 객체의 프로퍼티가 된다. window 객체의 메소드는 전역 함수이고 프로퍼티는 전역 변수가 된다. BOM의 요소들도 모두 해당 객체의 프로퍼티가 된다.


브라우저 창 크기 조절

window 객체의 innerHeight와 innerWidth 프로퍼티를 이용하면 브라우저의 창 크기를 설정할 수 있다. 여기서 브라우저 창이란 웹 브라우저의 뷰포트를 의미하며 브라우저의 툴바나 스크롤 바는 포함되지 않는다.

// 기본 문법
window.innerHeight
window.innerWidth

// 익스플로러 5부터 7버전만을 위한 문법 1
document.documentElement.clientHeight
document.documentElement.clientWidth

// 익스플로러 5부터 7버전만을 위한 문법 2
document.body.clientHeight
document.body.clientWidth

위 문법을 이용한 예제이다.

var windowWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
var windowHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
document.write("웹 브라우저의 너비는 " + windowWidth + "픽셀이고, 높이는 " + windowHeight + "픽셀입니다.");

window 객체의 모든 메소드나 프로퍼티를 사용할 때는 window라는 접두사를 생략할 수 있다.
따라서 위의 예제에서 window.innerWidth 대신 그냥 innderWidth를 사용해도 정상적으로 동작한다.

alert("전역 함수 호출시 window 접두사 생략 가능함!");                     // 전역 함수
document.write("현재 브라우저의 수평 위치는 " + screenX + "입니다.<br>"); // 전역 변수
document.write("현재 브라우저의 수직 위치는 " + screenY + "입니다.<br>"); // 전역 변수
document.write(document.title);                                           // 전역 객체

위 예제처럼 자바스크립의 모든 전역 객체, 전역 함수, 전역 변수를 사용할 때는 window 접두사를 생략할 수 있다.

screenX는 해당 브라우저 창의 왼쪽 모서리와 사용자 스크린의 왼쪽 모서리 사이의 거리를 반환한다. 또한 screenY는 해당 브라우저 창의 위쪽 모서리와 사용자 스크린의 위쪽 모서리 사이의 거리를 반환한다.


브라우저 새 창 열기

window 객체의 open() 메소드를 이용하면 새로운 브라우저 창을 열 수 있다.
또한 새로운 브라우저 창의 세부적인 옵션도 일일이 설정 가능하다.

  ```js
// 기본 문법
window.innerHeight
window.innerWidth

// 익스플로러 5부터 7버전만을 위한 문법 1
document.documentElement.clientHeight
document.documentElement.clientWidth

// 익스플로러 5부터 7버전만을 위한 문법 2
document.body.clientHeight
document.body.clientWidth

위 문법을 이용한 예제이다.

var newWindowObj;
// 변수 strWindowFeatures를 통해 새롭게 여는 브라우저 창의 옵션들을 일일이 설정할 수 있음.
var strWindowFeatures = "menubar = yes,location = yes,resizable = yes,scrollbars = yes,status = yes";

function openWindow() {
  newWindowObj = window.open("/html/intro", "HTML 개요", strWindowFeatures);

}

JavaScript Class

https://ko.javascript.info/class

var, let, const

https://velog.io/@bathingape/JavaScript-var-let-const-%EC%B0%A8%EC%9D%B4%EC%A0%90

1개의 댓글

comment-user-thumbnail
2022년 9월 12일

최고!

답글 달기