본문 바로가기
JavaScript

[JavaScript] JS의 기본 (특징, 문법)

by 이잔디 2022. 3. 4.

1. 특징

- HTML, CSS와 함께 웹을 구성하는 요소 중 하나로 웹 브라우저에서 동작하는 유일한 프로그래밍언어

- 개발자가 별도의 컴파일 작업을 수행하지 않는 인터프리터 언어

- 각 브라우저별 JS엔진은 인터프리터와 컴파일러 장점을 결합하여 비교적 처리 속도가 느린 인터프리터의 단점 해결

- 명령형, 함수형, 프로토타입 기반 객체지향 프로그래밍을 지원하는 멀티 패러다임 프로그래밍 언어

 

- 웹 브라우저는 JS를 HTML과 함께 다운로드하고, 브라우저의 JS 엔진이 JS를 실행

- 클래스가 존재하지 않는 프로토타입 기반의 객체지향 언어(Edition 6에서는 class 개념 지원)

- ECMAScript 스펙을 준수하는 방식으로 JS를 지원 

2. 선언 방법

- HTML에 포함하는 방법
<script type = "text/javascript">
	...
</script>

- 외부 JavaScript 파일을 HTML문서에 포함
<script src = "index.js" type = "tex/javascript"></script>

* 외부로 불러오면서 그 사이의 <script>에 코드를 작성하면 실행이 안된다.
<script src = "index.js" type = "tex/javascript">
...
</script>

- HTML5부터는 type속성 생략 가능

- src : 외부의 JS파일을 HTML문서에 포함할 때 사용, 생략가능!

- type : 미디어 타입을 지정할 때 사용. 

 

📌  <body> 안의 끝부분에 <script> 태그를 둘 것을 권장

 

→ <head>나 <body> 안 어느 곳에서나 선언이 가능하지만, <head>안에 위치한 JS 브라우저의 입/출력 발생 이전에 초기화되므로 브라우저가 먼저 점검한다. 그래서 <body>안에 위치하면 브라우저가 HTML부터 해석하여 화면에 나타나기 때문에 사용자가 빠르다고 느낀다. 

 

→ 웹 브라우저가 HTML문서를 순차적으로 파싱하므로, script 위치에 따라 로드와 실행시점이 달라짐!

 

3. 기본 문법

 주석

- Java와 같이 한 줄 주석은 //code, 블록 주석은 /*code*/로 표기

 변수

- 변수를 선언할 때 타입을 명시하지 않음

- 동적 타입언어 / 변수의 타입 지정없이 값이 할당되는 과정에서 자동으로 변수의 타입이 결정 

- ECMAScript 표준에 따라 낙타 표기법(Camel case)를 사용

 

🎀 ES6 - var, let, const

- ES5까지는 식별자에 값을 넣는 변수의 기능은 var 키워드만 사용

- ES6부터는 let과 const 키워드를 추가

- 상수 표기법은 모든 문자를 대문자를 사용하고 단어사이는 _로 표기하는 것을 권장

키워드 구분 선언 위치 재선언
var 변수 전역 스코프 가능 
let 변수 해당 스코프 불가능
const 상수 해당 스코프 불가능

 

📌  let과 const만 사용하는 것이 권장된다. (var 사용X)

 

🪄 변수 호이스팅(Variable Hoisting) 

- var 키워드를 사용한 변수는 중복해서 선언이 가능

- 호이스팅 : var 선언문이나 function 선언문 등 모든 선언문이 해당 Scope의 처음으로 옮겨진 것처럼 동작하는 특징

 

→ 즉, Javascript는 모든 선언문이 선언되기 이전에 참조 가능

// error가 발생하지 않고 콘솔에 undefined가 출력
// 모든 선언문이 호이스팅되기 때문에!!
console.log(number); // undefined

// number가 호이스팅 되어 첫 줄에 var number;가 옮겨진 것 처럼 동작된다. 
// 이때는 선언 및 undefined으로 초기화가 일어난다. 실제 100이 할당되는 것은 아래에서 실행된다. 
var number = 100;
console.log(number); // 100
{
    // JS는 블록레벨 스코프를 가지지 않고 함수 레벨 스코프만 가짐
    // number는 전역 변수이므로 전역에 선언한 변수 number에 두번째 number에서 재할당되기 때문에 10을 가짐 
	var number = 10;
}
console.log(number); // 10

 

🔑 이러한 문제를 개선하기 위해서 ES6에서 const, let이 추가되었다. 

• 자료형

- 원시 타입(primitive type)과 객체 타입(object type)으로 분류

- 원시 타입에는 숫자, 문자열, boolean, null, undefined와 같이 5가지가 있다. 이를 제외한 모든 값은 객체 타입.

자료형 typeof 출력 값 설명
숫자 number 정수 또는 실수
문자열 string 문자, '' or ""로 표기
boolean boolean 참(true) or 거짓(false)
null object 값이 존재하지 않을 경우
undefined undefined 변수가 선언되었지만 초기화되지 않을 경우

✔︎ 숫자 

- 정수와 실수로 나누어 구분하지 않음

- 모든 숫자를 8byte의 실수 형태로 처리 

- 숫자의 연산 처리시 실수 형태로 하기 때문에 특정 소수점을 정확하게 표현하지 못한다. 

 

- underflow, overflow, 0으로 나누는 연산에 대해 예외를 발생시키지 않는다. 

- Infinity : 무한대를 나타내는 상수, 어떤 수를 0으로 나누거나 Infinity를 어떤 수로 사칙연산한 결과

- NaN(Not a Number) : 계산식의 결과가 숫자가 아님을 나타냄

// Infinity 예제
console.log(10 / 0);
console.log(-10 / 0);
console.log(Infinity / 0);
console.log(-Infinity / 0);

// NaN 예제
console.log(0 / 0);

 

✔︎  문자열

- 16비트의 Unicode 문자를 사용

- 문자 하나를 표현하는 char와 같은 문자형 제공하지 않음

- '', "" 둘 다 사용 가능

- 이스케이프 시퀀스(\)도 사용 가능

 

🎀 백틱 (₩)

 

✔︎ boolean, null, undefined

- 비어 있는 문자열, null, undefined, 숫자 0은 false로 간주

- null은 값이 없거나 비어 있음을 뜻하고, undefined는 값이 초기화 되지 않았음(정의되지 않음)을 의미

- 둘 다 의미가 비슷하지만 값을 할당하지 않은 변수는 undefined가 할당되고(시스템 레벨), 코드에서 명시적으로 값이 없음을 나타낼 때(프로그램 레벨)는 null 사용

let a;
let b = null;

console.log(a); // undefined
console.log(b); // null

// JS합수는 무조건 반환값을 가지기 때문에 return을 안해준다면 defualt로 undefined를 리턴
fuction f(){
	...
}
let c = f();
console.log(c); // undefined

• 연산자

== : 동등 관계인지 확인 

=== : 값이 일치하는지 확인(타입 포함)

let num = 100;
let str = "100";

console.log(num == str); // true
console.log(num === str); // false

• 조건문, 반복문

- 조건문 : if, switch

- 반복문 : while, do-while, for

for(초기화; 조건식; 증감표현식){
	...
}

for(var 변수 in 배열 or 객체){
	...
    // 변수에는 배열의 인덱스 
    // 객체의 프로퍼티 명
}

- break, continue 존재

- Java와 동일하다. 

- semi boolean이 존재하기 때문에 신경써서 조건을 생성한다. 

4. 객체(Object)

- 이름과 값으로 구성된 프로퍼티의 집합

- primitive type을 제외한 모든 값이 객체

- 키(Key)와 값(Value)으로 구성된 프로퍼티(Property)들의 집합

- 전역 객체를 제외한 JS객체는 프로퍼티를 동적으로 추가하거나 삭제 가능

- JS의 함수는 일급 객체이므로 값으로 사용할 수 있다. 즉, 프로퍼티의 값으로 함수를 사용 가

- 프로토타입(prototype)이라는 특별한 프로퍼티 포함

• 생성

✔︎ 객체 리터럴 

- { }를 사용하여 객체 생성

- { } 내에 1개 이상의 프로퍼티를 추가하여 객체 생성

let obj = {};

let info = {
    name : "jandi",
    age : 22,
    str : function(){
        // 이때 this를 사용해서 부르지 않으면 오류가 난다. 
    	console.log(this.name + ' ' + this.age);
    },
};

 

✔︎ Object 생성자 함수

- new 연산자와 Object 생성자 함수를 호출하여 빈 객체 생성

- 빈 객체 생성 후 프로퍼티 또는 메소드를 추가하여 객체 완성

let info = new Object();

obj.name = "jandi";
obj.age = 22;
obj.str = function(){
    	console.log(this.name + ' ' + this.age);
        };

 

✔︎ 생성자 함수

- 동일한 프로퍼티를 값는 객체 생성 시 사용 → 재사용가능!

- 템플릿(클래스)처럼 사용하여 프로퍼티가 동일한 객체 여러개를 간단히 생성 가능

function Info(name, age){
    this.name = name;
    this.age = age;
    this.str = function(){
    	console.log(this.name + ' ' + this.age);
    };
}

let person1 = new Info('jandi', 22);
let person2 = new Info('jandidi', 24);

• 값(Value) 조회

- 객체는 dot(.)을 사용하거나 대괄호([])를 사용해서 속성값에 접근 가능

- 객체에 없는 속성을 접근하면 undefined를 반환 

- 객체 속성 값을 조회할 때 || 연산자를 사용하는 방법도 가능

let obj = {};

let info = {
    name : "jandi",
    "name-k" : "잔디",
    age : 22,
    str : function(){
        // 이때 this를 사용해서 부르지 않으면 오류가 난다. 
    	console.log(this.name + ' ' + this.age);
    },
};

console.log(info.age);
console.log(info[age]);

// * 속성명에 연산자가 포함된 경우 [] 표기법만 접근가능!
console.log(info["name-k"]); // 잔디
console.log(info.name-k); // NaN

• 값(Value) 변경, 추가, 제거

- 변경 : dot(.) 이나 [] 사용

- 추가: 객체의 값을 할당하는 속성이 없을 경우, 속성이 추가 

- 제거 :  delete 연산자를 이용해 속성 제거

 

let obj = {};

let info = {
    name : "jandi",
    "name-k" : "잔디",
    age : 22,
    str : function(){
        // 이때 this를 사용해서 부르지 않으면 오류가 난다. 
    	console.log(this.name + ' ' + this.age);
    },
};

// 변경
info.age = 25;
info["age"] = 25;

// 추가
info.tel = '010-0000-0000';

// 제거
delete info.name;

• 참조

- 객체는 복사되지 않고 참조된다. 

- primitive type이 아닌 모든 값은 참조 타입

- Object, Array, Date, Error 포함

- 타입 확인 방법으로는 typeof 연산자가 있다. (null은 primitive지만, object를 반환)

5. 함수(function)

• 선언, 호출 

- JS에서 함수는 일급 객체이다. (function is value. 함수가 값이 될 수 있다.)

- 함수를 변수, 객체, 배열 등에 저장할 수 있고 다른 함수에 전달하는 전달 인자(콜백함수) 또는 리턴 값으로 사용가능

- 함수는 프로그램 실행 중에 동적으로 생성 가능 

- 매개변수에 대한 타입은 명시하지 않는다. 

- 함수를 호출할 때 매개변수와 전달인자의 개수가 일치하지 않아도 호출 가능

 

✔︎ 함수 선언문 

function 함수이름(매개변수){
	...
}

함수이름(매개변수); //함수 호출

 

✔︎ 함수 표현식

let 함수이름 = function(매개변수){}

함수이름(매개변수); //함수 호출

 

✔︎ fuction 생성자(cunstructor)함수  

let 함수이름 = new Function("매개변수", "함수내용");

함수이름(매개변수); //함수 호출

// 예시
let sum = new Function("num", 
    "console.log(num + num);");

• 함수 호이스팅

- 함수 선언문의 경우 함수 선언의 위치와 상관없이 코드 내 어디서든지 호출 가능

- JS는 var, function을 호이스팅한다.

- 함수 선언문으로 정의된 함수는 JS엔진이 스크립트가 로딩되는 시점변수객체를 저장. 함수 선언, 초기화, 할당이 한번에 이루어짐

let res = minus(10, 3); // 함수 호이스팅이 발생
console.log(result); // 7

function minus(n1, n2){
    return n1 - n2;
};

* 함수 선언문으로 함수를 정의 했을 때 함수 호이스팅으로 사용하기 쉽지만, 대규모 개발의 경우 너무 많은 코드를 변수객체에 저장하여 어플리케이션의 응답속도를 저하시킬 수 있다는 단점이 있다. 

 

- 함수 표현식의 경우 함수 호이스팅이 아니라 변수 호이스팅 발생

let res = minus(10, 7); // TypeError 발생
console.log(res);

let minus = function(n1, n2){
    return n1 - n2;
};

 

function a(){
    consol.log("a1");
}

a(); // a2

function a(){
    consol.log("a2");
}

a(); // a2

// 함수 호이스팅으로 마지막것으로 초기화된다.

• 콜백 함수(Callback function)

- 함수를 명시적으로 호출하는 방식이 아니라 특정 이벤트가 발생했을 때 시스템에 의해 호출되는 함수를 말함

- 일반적으로 콜백 함수는 매개변수를 통해 전달되고 전달받은 함수의 내부에서 어느 특정시점에 실행

- 주로 비동기식 처리 모델에서 사용 → 처리가 종료되면 호출될 함수(콜백함수)를 미리 매개변수에 전달하고 처리가 종료되면 콜백함수를 호출

<button id = "btn"> click </button>
<script>
    let btn = document.getElementById('btn');
    btn.addEventListener('click', function(){
        console.log(click!);
    });
</script>

 

/* 
일정시간 후 함수 한번 호출
setTimeout(실행할 함수, 딜레이 타임(ms));
clearTimeout;

일정시간 간격으로 함수 계속 호출
setInterval(실행할 함수, 시간 간격(ms));
clearInterval;
*/

let a = function(){
    console.log('a');
}

setTimeout(a, 3000); // 3초뒤에 함수 a가 전달되어 실행
let obj = setInterval(a, 3000); // 3초 간격으로 함수 a가 계속 호출

setTimeout(function(){
    clearInterval(obj); // clearInterval로 obj를 멈출 수 있음
}, 5000);