T.I.L 2nd Week (Javascript)

안희수·2021년 5월 10일
4

TIL

목록 보기
3/26
post-thumbnail

문서 작성 이력

  • 2021.05.10 Rev_No.0 Today_I_Learned (2주차) 문서 초안 작성

Javascript

블로그 작성에 앞서 설명

해당 글은ES6 기준으로 작성된 자바스크립트 사전 스터디 내용임을 밝힘

일반화가 가능한 보편적 자료(자바스크립트의 역사 관련)는
다른 블로그에서 내용을 발췌해 올 수 있으나,

기술 표준과 관련 정보는
Ecma International 에서 배포하는 ECMA-262의 내용을 참고로 하며,
비교 설명을 위해 ES6 이전의 구 자바스크립트를 인용해 올 수도 있음.

관련 주소

ECMAScript® 2020 Language Specification
작성일이 2021년 5월 10일 이므로 2021년 기준

진행 목차 (INDEX)

1.자바스크립트의 역사
부제 Java === Javascript ?

매우 당연한 이야기이지만
자바스크립트와 자바는 완전히 별개 언어이다.
처음부터 자바스크립트의 역사 설명을 하기에는
다소 지루하게 느껴 질 수도 있어 쉬어가는 의미로 작성하였다.


JavaScript 와 Java
[이미지1]
출처_01 참조


이 두 언어의 비교는 탄생 배경부터가 극명하게 갈리므로

[자바의 탄생 배경]
가전제품 및 모바일 기기에서 구동하기 위해 만들어짐

[자바스크립트의 탄생 배경]
웹 브라우저 상에서 웹페이지를 동적으로 작동시키기 위해 만들어짐

이름만 비슷할 뿐 성격이나 구동 방식이 엄연히 다른 언어이다.


JavaScript 의 역사

[이미지2]
출처_02 참조


작성 목적이 기술 블로그를 남기기 위함이고
컴퓨터 공학 전공자들의 이론 수업이 아니므로
지나치게 세세한 역사 설명은 생략하고
의미 있는 분기점에 대해서만 살명하고자 한다.

자바스크립트 주요 역사적 분기점

  • 1995년
    Brendan Erich 에 의해 처음 자바스크립트가 만들어졌다.

  • 1996년 ~1997년
    ECMA-262 라는 자바스크립트 표준이 만들어지기 시작했다.

  • 1999년 ~ 2001년
    동적인 HTML 페이지
    그리고 XMLHttpRequest 와 JSON 의 등장
    HTML에서 문서객체모델(DOM)을 사용할 수 있게 되면서
    페이지와 컨텐츠를 동적 생성할 수 있게 되었고
    XML과 JSON을 통해 텍스트 형식으로 데이터를 주고 받을 수 있게 되었다.


    JSON (JavaScript Object Notation)
    Key : Value 로 이루어진 데이터 객체를 전달하는 개방형 표준 포멧

    JSON 관련 예제

    { 
      “first”: “Jane”,
      “last”: “Porter”,
      “married”: true,
      “born”: 1890,
      “friends”: [ “Tarzan”, “Cheeta” ] 
    }
  • 2005년
    Ajax의 등장
    JavaScript 의 비동기 처리가 가능해지면서
    전체 페이지를 로드하지 않고도 페이지를 생성할 수 있게 되었고
    SPA(Single Page Appication)구현이 가능해짐
    양뱡향 통신이 가능해졌다.


    Ajax (Asynchronous JavaScript and XML)
    필요한 데이터만을 웹서버에 요청해서 받은 후
    클라이언트에서 데이터에 대한 처리하는 기술


    Ajax를 깊게 들어가고자 한다면
    SOAPXML 관련 기술 지식에 대한 이해도 필요하지만
    자바스크립트를 기술하고자 하는 목적을 벗어나기 때문에
    본문에 추가 기술하지는 않고 링크로 대체하며
    간단히 설명하자면 SOAPXML 은 웹서비스 프로토콜이다.

  • 2006년
    제이쿼리의 등장과 호환성 지옥의 해방
    제이쿼리라는 프레임워크의 등장으로
    크로스 브라우징 문제가 어느 정도 해결이 된다.
    제이쿼리는 자바스크립트 관련 기술로 추가 설명

  • 2009년
    Node.js 의 등장
    이벤트 기반의 non-blocking I/O
    Node.js 라는 서버사이드 자바스크립트로
    서버를 구현할 수 있게 되었으며
    이로 인해 자바스크립트 개발자는 친숙한 언어로
    클라이언트에서 서버까지 구현이 가능해졌다.

    Node.js를 사용하지 않았던 시절에는
    벡앤드 개발자가 JSP, PHP, ASP 같은
    Server Side Language를 통해
    서버와 클라이언트를 연동시켜 주어야 했다.


  • 2006년
    제이쿼리의 등장과 호환성 지옥의 해방
    제이쿼리라는 프레임워크의 등장으로
    크로스 브라우징 문제가 어느 정도 해결이 된다.
    제이쿼리는 자바스크립트 관련 기술로 추가 설명

2.Null && '' && 0 && undefined


말머리

2.Null && '' && 0 && undefined 항목만
유일하게 말머리를 달아 둔 이유를
밝히고 넘어가려고 이 글을 적는다.

이 기술 블로그 내용의 작성된 내용 중 아마 해당 파트가 가장
비중 있게 다뤄질 것 같다.

대부분은 엘리의 드림코딩 이라는 유튜브 강의를 듣고
기술 블로그를 작성하기 때문에 내용들이 거의 대동소이 할 것이고
무언가 화려하고 있어보이는 기능을 구현한 내용들도 나올 것 같지만
기본을 확실하게 짚고 넘어가고 싶어서
데이터 형식에 좀 비중을 많이 두려고 한다.

이유는 JAVA 혹은 C 계열 언어와 달리
자바스크립트는 거의 데이터 형태가 없다시피 한 언어이기 때문이다.
완전히 없다는 뜻은 아니고 자유롭다는 것이 장점이자 단점이다.
너무 자유 분방하다 보니 때때로 오히려 낭패가 되서
근래에는 자바스크립트이면서도 처음부터 데이터 형을 명시하는
TypeScript 라는 언어가 생겨났다.
한마디로 요약하면 자바스크립트의 상위 호환


전반적인 설명을 하기 앞서
예시 코드를 하나 놓고 설명을 시작하려고 하는데
Null 과 Null 이 아닌 데이터 (number or string) 을 구분하는 것은
쉽지만 null 과 undefined 를 구분하는 것은
처음 자바스크립트를 사용하는 사람들이 많이 혼동하는 부분이다.

먼저 NULL 은 값이 없다는 의미이다.
의미적으로 값이 없다라는 뜻이지
실제로는 "값으로써 의미가 없는 고유의 값" 이다.


그에 비해 undefined 라는 것은 정의되어 있지 않다는 뜻으로
변수 혹은 객체 (자바스크립트에서는 변수도 객체이다) 를 선언할 때
아무런 값도 주지 않으면 해당 객체는 undefined 가 된다.


해당 자바스크립트 로그를 보여주는 또 다른 이유 중 하나는
의도적으로 변수에 null 이라는 값을 주었을 때
어떤 일이 발생하는지를 설명하기 위해서이다.

null 이라는 값을 null_data 라는 변수에 주었을 때 값은 null 이 맞지만
해당 변수의 형식까지 null 이 되지 않은 것을 볼 수 있다.
오히려 null 이라는 값을 준 null 데이터의 형식은
object로 바뀐 것을 알 수 있다.

때문에 type of 를 잘못 사용하면 낭패를 볼 수 있다.

이유는 2가지인데

첫 번째
type of 로 물어본 것은 문자열로 반환된다.
즉 정의되지 않음 값에 대해서 undefined 이 아니라 'undefined' 로 날아온다.


두 번째
type of 로 판단하려는 것이 객체일 경우 object 의 형태로 돌아올 수 있으니 해당 값이 null 인지 아닌지를 판단하려고 한다면


if (type of a === null) { // do something; }

가 아니라

if (a === null) { // do something; }

로 알아보는 것이 더 유효하다.


Null 이냐 아니냐를 판단할 때는 확인할때는 값으로 비교하는 것이
유효하지만 string 혹은 number 로 들어가 있을 때는 그 반대가 된다.

가령

let no = 1;

라고 값을 선언한다면 type of 와 === number 를 통해 비교하면
다음과 같은 결과가 발생한다.


이유는 type of 로 비교한 것은 'No' 라는 변수 안에 들어 있는
1 이라는 값이다.
Number 라고 하는 것을 number 와 같은 형태로 혼동 할 수 있는데
Number 의 타입은 functinon 이라고 나오는 것을 볼 수 있다.


Number 가 무엇인가 하면 바로 자바스크립트가 제공하는 내장 함수 라는 기능이다. 이것이 어떤 의미인가 하면

Number. 이라고 작성하였을 때 나타나는 저 내용들이
바로 내장함수에서 제공하는 여러가지 기능들 중 하나이다.

만약 Number 함수를 통해 해당 값이 정수형인지
확인하고 싶다면 type of 가 아닌 Number.isInteger 을 사용하면 된다.


부가적으로 더 설명하면 'NaN'을 짚고 넘어가고자 한다.
NaN 은 Not A Number 의 약자로 표현 불가능한 수치형 결과이다.
'0' 이 NaN 이 아니냐 말할 수 있지만 그것은 아니다.

이유는 자바스크립트의 자유분방함 때문이라 볼 수 있는데
우선 '0' == 0 은 true 이다.
자바스크립트가 동등 비교를 할 때 다른 프로그래밍 언어들과 다르게
삼항연산자 === 을 사용해야 하는 이유로
자바스크립트는 '0' 과 0 을 의미적으로 같은 값으로 간주한다.
완벽한 동등 연산자를 사용하기 위해서는 == 이 아니라 ===
자바스크립트에서는 강제되고 있는 사항이라 짚고 넘어가야 할 것 같다.


NaN 으로 비교되는 대상은 계산상으로 있을 수 없는 값
대표적인 것으로 0 나누기 와 같은 상황에서 쓰인다.


해당 사진은 임의의 숫자를 계산기에서 0으로 나누어 본 결과이다.
수학적으로는 있을 수 없는 수이고
컴퓨터 상에서도 연산할 수 없는 대상이다.


프로그래밍 하는데 전혀 상관 없는 경우라 생각하겠지만
가장 중요한 사항이라고 볼 수 있겠다.
0 나누기 오류는 현업에 있었을 때 수도 없이 겪어본 상황으로
심각한 시스템 오류를 야기 시켜서
프로그램을 멈추게 하는 요인이 되기도 한다.

무언가 수학적인 계산을 하는 프로그램이라 한다면
NaN 이 발생하는 상황을 최 우선적으로 제외시키고
프로그래밍을 해야 하므로 부가적으로 긴 설명을 하게 되었다.

그리고 0 과 '' 설명이 남았는데 이 둘은 좀 묶어서 설명하려고 한다.

JAVA 의 경우 특히 그러한데 데이터 형 명시가 매우 엄격하다.
주 개발 언어였던 C# 도 JAVA 의 객체 지향 형태를 지향하다보니
데이터형은 제일 중요한 문제였다.

만약 JAVA 나 C# 에서 변수 (정수형,문자형) 을 선언하려면
어떻게 해야 할까 ?

int A;
string B;

이렇게 선언했을 경우 A 와 B 는 Null 이 된다.
두 값을 초기화 하려면
A 의 경우는 A = 0;
B 의 경우는 B = ''(혹은 String.Empty); 를 지정해 주어야 한다.
다만 A 라는 변수에 0 을 대입하는 것은 애매할 수도 하는데
값을 초기화하는 의미에서 0 을 대입한 것과 자연수 0 이 충돌한다.

초기 값으로 '' 과 0 을 대입할 수도 있다. 인지적 측면으로 본다면
'' 이라는 값은 아무 값도 들어오지 않은 상황이기 때문에
Null 이 아닌가 혼동할 수도 있을 것이다.

특히나 JAVA를 선행 학습하고 왔다면
String.isNullOrEmpty 라는 함수를 사용한 기억 때문에
'' 은 값이 없다 라고 혼동의 여지가 있겠지만

JAVA에서도 '' 은 공백이지 Null이 아니고 문자형 데이터이다.

이미 문자형 변수로 선언했기 때문에 문자형이 맞다.
그리고 ' ' 는 이미 SpaceBar 입력이 들어갔기 때문에 애시당초 논외

공백 '' 에도 사실 값은 존재한다.
문자열은 이진 바이너리화 되는 시점에 아스키 코드로 변환이 되는데
아스키 코드로 '' 는 32 라는 값을 가진다.

참고로 Null 도 아스키 코드를 가지고 있는데 아스키코드로 0
(16진수로는 0X00) (2진수로는 0)

이것이 '' 이 아무런 입력을 받지 않은 초기 값임에도
자바스크립트에서 string 이라는 데이터 형식을 가진 이유와
0 이 number 라는 데이터 형식을 가지는 이유이다.

0 은 초기화에 대한 언급도 필요 없이 그 자체로 자언수이다.


3.자바스크립트는 절차지향 언어이다 ?

자바 스크립트 강의를 어설프게 봐서 그런지 헷갈리긴 하는데
이건 자바스크립트 헤비 유저가 아니라서 정확히 단정짓지는 못하겠다.
많은 기술 블로그 검색을 통해 보면 절차 지향이다 객체지향이다
의견이 분분하다.

그런데 그냥 보면 절차지향 방식으로도 프로그래밍이 되고 객체지향으로도 프로그래밍이 된다.
다만 근래 까지는 높은 확률로 절차지향식으로 자바스크립트를 프로그래밍하고 있었고 객체지향에 대한 언급을 할 때는 프로토타입이 거의 필수적으로 언급이 된다.

그래서 자바스크립트는 절차지향인가 라고 말머리를 달았지만
프로토타입에 대해서 더 짚고 넘어가야 할 것 같다.

먼저 이야기 해야 하는 부분은 자바스크립트는 클래스가 없다.
객체지향 언어로 대표되는 Java 혹은 C#을 다뤄봤다면
클래스가 없는데 객체 지향이라는 말에 조금 의문을 가질 수도 있다.
참고로 절차지향에 대표적인 언어인 C 는 클래스를 가지고 있지 않고
C++ 이 최근에서야 클래스를 지원하기 시작했다고 얼핏 듣기는 한 것 같다.

보편적으로 객체지향 언어는 객체 클래스가 있어 클래스를 생성하고
클래스의 인스턴스에 해당하는 개별 객체를 생성할 수 있게 된다.

예시코드 JAVA

// 자바 커리큘럼 중 가장 흔한 예시인 학생 클래스 구현
public class Student {
	public string name; // 이름
	public int age; // 나이
	public string gender; // 성별
	public string class; // 학급 
    // 학생의 이름을 가져오는 method
    public string get_name () {
    	retunr this.name;
    }
    // 학생의 이름을 지정하는 method
    public void set_name (string _name) {
    	this.name = _name;
    }
    // age, gender, class 등의 대한 구현은 생략
}

// Student 클래스를 통한 객체 구현
Student st = new Student;
// 학생의 이름을 지정
st.set_name('안희수');
// 학생의 이름을 받아오기
system.out.println(st.get_name);

객체 지향에서는 new 생성자를 통해 클래스 인스턴스 객체를 생성하고
해당 인스턴스 객체는 독립적으로 역할을 수행한다. 자바스크립트는 클래스가 없어서 그동안은 객체지향 언어라고 할 수 없었지만 프로토타입이라는 것이 나오면서 객체를 생성하고 관리할 수 있게 되었고
최근에는 자바스크립트 코딩을 할 때 먼저 프로토타입을 선언하고
프로토타입에서 객체를 생성하여 사용할 것을 권장하고 있다.

추가로 객체지향 언어에서 보편화된 상속을 사용할 수 있다는 점에서
자바스크립트는 프로토타입 기반의 객체지향 언어로 평가하기도 한다.

객체지향 자바스크립트에 대해 자세하게 설명하고 있는 웹페이지
Jaehee's Web Club

4.자바스크립트 와 HTML을 연동할때
부제 ('',async, defer)

원래는 호이스팅에 대해서 작성하려다가 그것은 상식적인 수준에서 알고만 있으면 될 것 같고 이미 먼저 작성된 기술 블로그들이 많아서 구태여 중복해서 언급할 필요성을 느끼지 못해 비동기 자바스크립트 로드와 동기 자바스크립트 로드 방식에 대해서 설명하려고 한다.

HTML 페이지 구동 시 자바스크립트가 동기 방식일 경우 나타나는 문제

HTML 페이지를 만들먼서 꽤나 골머리를 썩게 한 문제중 하나였는데
빈 HTML 페이지에서 자바스크립트 공부를 하려고
Console.log 를 통해 자바스크립트 코딩을 할 때는 아무 문제가 없었는데

HTML 요소를 건드리는 과정에서 아무리 페이지를 갱신해도
자바스크립트가 동작하지 않는 경우가 종종 발생했다.
페이지가 로드됨과 동시에 동작해야 화면에 보여지는 부분이
자바스크립트가 동작하지 않음으로써 아예 보여지지 않거나
연속된 기능이 있어 상단에서 처리된 결과로 다른 무언가 동작을 하는데
상단 코드가 실행되지 않아 에러가 발생하는 상황도 있었는데

문제의 원인은

<script src="js_study.js" type="text/javascript" async></script>

여기서 처럼 async 혹은 defer 이라 적지 않아서 HTML 페이지 생성 완료 전에 자바스크립트가 먼저 구동이 된 탓이었다.
자바스크립트는 HTML 요소가 아직 만들어지지 않아서 접근 불가
반대로 자바스크립트가 무거우면 자바스크립트로 동적인 생성을 하는 부분이 딜레이가 되면서
화면에 정상적으로 표현되지 않는 문제가 발생할 수 도 있음


예전에는 자바스크립트를 Body 태그 최하단에 지정함으로써 이러한 문제를 회피해 나갔지만
자바스크립트가 무거운 경우는
상기 언급한 대로 자바스크립트 다운로드 완료 전까지
페이지가 프리징 되거나 정상적을 표현되지 않을 수 있는 문제가 발생할 수 있어
현재는 거의 권장되지 않는 방법이다.

현재는 defer 와 async 를 주로 많이 사용하고 있는데
후술할 내용으로 인해서 보통 defer를 가장 많이 선호해서 사용한다.

async
비동기적으로 자바스크립트를 호출하는 것으로 스크립트 다운이 완료되는 것을 기다리지 않고 HTML 페이지 내 컨텐츠를 출력 처리하지만
비동기 적으로 자바스크립트가 실행되면 HTML 파싱을 멈추게 된다.


defer
지연 스크립트라고 해서 백그라운드에서 자바스크립트를 다운로드한다. 스크립트 다운로드 중에도 HTML 파싱은 멈추지 않고 스크립트 실행은 페이지 구성이 끝날 때까지 지연된다.


defer 를 명시하지 않아서 발생하는 문제점으로
본인이 겪은 대표적인 문제 상황 2 가지

1. setInterval 기능을 이용한
시계 display 를 하는데
태그를 못 찾아가는 문제


2. addEventListener 기능을 이용하여
마우스 클릭 이벤트에 대한 처리를 하는데
태그를 못 찾아가는 문제

5. 'let' 'var' 'const' 대한 차이와 Arrow Function

let var const 에 대한 내용은 크게 깊게 설명할 여지는 없으므로
간단하게 섦명하고자 한다.

Const : 상수라는 의미로 최초 선언 이후로 변하지 않는 불변의 값이다.

let : ES6 에 와서 추가된 내용으로 그 전에는 var 를 변수로 사용하였다. let 과 var 에 가장 큰 차이점은
var는 함수 scope 까지 가지고 있어 var 에 function 을 담을 수 있다는 점이고

다른 언어에서는 변수에 함수를 담는다는 것을 상상할 수도 없다.

let 은 block 형 scope 이기 때문에 지역 변수로 let 을 권장한다.

let 을 권장하는 이유로는 ES5 에서 추가된 "use strict" 을
자바스크립트 상단에 명시하면 한번 선언된 변수 이름을
다른 구역에서 또 선언할 수 없다.

"use strict" 없이 var 로만 변수를 선언할 경우
위에서 var A 라고 선언 후 하단 어딘가에서 var A 라고
다시 선언할 수 있는데 만약 이 'A' 라는 변수가
해당 페이지에서 매우 중요한 무언가이고 정수형 데이터인데
우연히 누군가 또 다시 'A' 로 선언한 후
이를 문자형 데이터로 바꾸었다고 생각해보자.
현업에서 매우 식겁할 수 있는 상황이다.

추가적으로 지역변수 전역변수 측면에서 부가 설명을 하자면
let 은 대체로 지역 변수 할당하는데 사용하지만
var 변수를 스크립트 최 상단에서 선언하거나
function 바깥에서 선언한 경우
본래 설명 하려다가 생략한 호이스팅에 의해서
자동적으로 스크립트 최 상단으로 끌어 올려진다.

이런 경우 var 를 전역 변수로 볼 수 있는데
ES6 이전에는 var 를 명시하지 않고
그냥 A = 1; 이라고 변수를 선언하는 것이 말도 안되지만 가능했었다.

상단에서 데이터 형을 설명할 때 언급하였지만
자바스크립트는 기본 데이터형이 object 이고
var 스코프를 사용하지 않은 변수는
암묵적으로 window 객체에 종속되는것으로 간주하는 데
window 객체는 모든 구성 요소 최 상단의 브라우저를 지칭하는 것으로
ES6 이후 부터는 거의 지양되거나 기피해야 하는 변수 선언 방식이다.


Arrow Function 은 조금 더 추가적으로 간단하게 언급하고자 하는데
이론적으로 깊게 설명하고자 함은 아니고 이런 표현식도 가능하다 라는 것을 부수적으로 설명하기 위해 언급하는 바이다.
본인은 Arrow Function 을 보면서 Lamda 식이 떠올랐었다.

Arrow Function 에 대한 예제

// 버튼 태그에 클릭 이벤트를 구현한 소스 코드
openbtn.addEventListener('click', e=> {

                if(pop.clientHeight === 0) {

                    pop.style.visibility = 'visible';
                    pop.style.height = '170px';
                    openbtn.innerText = 'Close Popup';
                   openbtn.style.backgroundColor = '#2196F3';
                } else {
                    pop.style.visibility = 'hidden';
                    pop.style.height = '0px';
                    openbtn.innerText = 'Open Popup';
                    openbtn.style.backgroundColor = '#2195f3a4';
                }

            }); 
           
// 만약 Arrow Function 을 사용하지 않을 경우
openbtn.addEventListener('click', e=> { //가 아니라
openbtn.addEventListener('click', function(evnt) { 
//로 길게 짜야 했을 것이다.

부록(인용 자료)

출처_01 [이미지1] https://images.app.goo.gl/mK8GoTivpMsQHu9B8
출처_02 [이미지2] https://images.app.goo.gl/4phj7oGqx2AHsb127

profile
9년차 소프트웨어 개발자 (2024년 재 개편 예정입니다)

1개의 댓글

comment-user-thumbnail
2021년 5월 13일

👏

답글 달기