본문 바로가기

Backend/Javascript

자바스크립트와 다른언어의 차이점

Javascript와 다른언어와 차별점

1. 자바스크립트는 동적 프로토 타입 기반 객체 지향언어이다.

객체지향언어에는 2가지의 큰 틀이 있다.

  • 클래스 기반 객체지향언어

  • 프로토타입 기반 객체지향언어

우선, 자바스크립도 객체지향언어라는 걸 잊지 말아야 한다. 하지만, Java와 다르게 클래스라는 개념이 없다.

ECMAScript5에서 많은 라이브러리가 클래스를 지원한 것처럼 보이게 하는 것들이 있다. 하지만 주의해야한다. 클래스 기반 언어와 다르다(C++, Java)

JS의 프로토 타입과 상속에 대해서는 다음 문서를 참고

https://sdcodebase.tistory.com/21?category=861404

 

자바스크립트의 프로토타입

JS의 프로토 타입 프로토 타입은 JS와 클래스 기반 객체지향언어와 크게 차이를 주는 부분이다. 프로토타입은 상속과 멤버 함수 추가등에 많이 쓰인다. 각각에 대해서 알아보도록 한다. 1. 생성자 안에서 메서드를..

sdcodebase.tistory.com

 

1.1. 클래스 기반 언어와 프로토타입 기반 언어의 차이점

  • 클래스 기반 언어는 객체의 형식이 정의된 클래스라는 개념을 가진다.

    • 붕어빵을 만든다고 가정하면, 붕어빵의 틀이 클래스 기반언어의 클래스이다.

  • 사람이라는 틀(class)이 있다면, 그 틀을 이용해서 사람들을 찍어내는 것(객체)이다.

 

  • 프로토타입 기반 언어는 클래스라는 개념이 없다. 클래스 기반 언어의 상속 개념과 다르게, 객체 prototype의 위임 과정을 통해 상속의 과정이 구현된다.

    • 클래스 기반 언어는 틀 자체를 상속시킨다. 상속시킨 틀을 이용해서 객체를 생성한다. 하지만, 프로토타입 기반 언어는 객체들을 prototype으로 연결시킨다. 클래스라는 개념이 없기 때문에, 객체들을 연결 할 수 밖에 없다.

  • 클래스를 기반 객체지향은 클래스 상속 정보를 이용해서 상속 구조 모습을 가진 새로운 객체의 틀을 뽑아낸다. 반면 프로토타입을 통한 상속 구조는 존재하는 객체끼리 연결을 동적으로 해서 표현한다.

    • 상속 받은 객체의 내용을 동적으로 추가 및 삭제할 수 있다.

  • 자바스크립트에 class, extends키워드가 나오기는 했다. 하지만, 내부 구현은 prototype으로 되어있다. Java의 클래스 상속과 다르다. 결국, 그런 키워드가 나왔다고 해도 프로토타입 객체지향언어의 틀은 잃어버리지 않는다.

  • 해당 함수는 생성자라고 부르지만, 정확하게는 생성자 함수 객체이다. 자바스크립트는 함수도 객체로 표현된다. Function을 __ proto __로 갖는다. Function객체를 상속받은 것이다.

2. 자바스크립트는 싱글스레드기반 비동기처리를 한다.

2.1. 비동기적인 Javascript

  • 일반적으로 우리가 C++언어를 작성하면, 해당 코드는 동기적, 순서대로 실행한다.

  • 하지만 자바스크립트는 비동기적이다. 작성된 순서대로 실행하지 않는다.

  • 만약 해당 코드가 C++언어와 같이 동기적으로 실행한다면, 1000ms있다가 hello1이 실행되고, 500ms있다가 hello2가 실행된다. hello1 -> hello2

  • 자바스크립트 엔진은 호출 스택이 1개인 단일 스레드이다. 그래서 hello2 -> hello1이 실행된다.

    • 사실 JS엔진이 단일 호출스택인 것은 맞다. 하지만, JS가 구동되는 환경(브라우저, Node,js)에서는 여러 스레드를 사용한다. 단일 호출스택인 JS엔진과 여러 스레드를 사용하는 환경을 상호작용하게 해주는 것이 Event loop이다(Node.js에서는 이벤트 루프를 지원하기 위해서 LIBUV라이브러리를 사용한다.)

    • 단일 스레드는, 한번에 단 한 개의 함수만 처리한다는 뜻이다.

2.2. 자바스크립트 실행 시스템

  • 자바스크립트 엔진은 memory heap과 call stack을 가지고 있다.

  • JS엔진 이외에도 JS를 실행 할때 관여하는 요소들이 있다. 우리가 아는 setTimeout, AJAX 등은 자바스크립트 그 자체 문법이 아니라, ***Web API***이다. JS에서 setTimeout을 실행하면, Web API해당 함수를 요청하는 것이다. 그리고 거기에 추가된, 콜백함수도 같이 WebAPI에게 전달한다.

  • setTimeout(1000,function a() {....})을 실행하는 과정을 보자

([Hudi님의 블로그] (지금까지 본 JS실행에 대한 그림 중에 최고..)

 

  1. JS에서 setTimeout을 요청한다 (그러면 call stack에서는 setTimeout함수가 사라진다. --> 현재 call stack은 빈 상태.)

  2. Web API에 있는 setTimeout에게 작업을 요청하고 call back 함수인 a를 전달한다.

  3. setTimeout은 1000ms를 기다리는 작업을 시작한다. (call back함수 a를 계속 가지고 있는 상태)

  4. setTimeout이 끝나고, a를 task queue에 전달한다.

  5. event loop는 call stack이 비는지 + task queue에 작업이 비는 지 계속 체크한다. (꺼지지 않는다) 현재 call stack이 비었고, task queue에 task가 있다는걸 체크한다.

  6. task를 call stack에 a를 둔다. 그러면, a를 실행한다.

  • event loop는 call stack이 비어야, task를 가져다 둔다.

그렇다면, 처음에 작성한 저 코드의 실행은 어떻게 되는 것일까?

  1. call stack에 각각 setTimeout(1000, a), setTimeout(500, b)가 쌓인다.

    • setTimeout함수는 바로 요청을 하고 스택에서 제거된다. (JS엔진에서 처리하는게 아니기 때문에 전달만 한다.)

  2. a를 JS엔진의 밖에 있는 WebAPI에게 넘긴다.

  3. b를 JS엔진의 밖에 있는 WebAPI에게 넘긴다.

  4. 500ms 후 , b를 task queue로 보낸다. call stack은 비어있고, task queue에 task가 있기 때문에, 이벤트 루프가 b를 call stack에 보내고 실행한다.

  5. 1000ms 후, a를 task queue로 보내고 이벤트 루프가 call stack으로 보내서 실행한다.

2.3. 비동기 단일 스레드의 의미

비동기라는 의미는 결국, 순서대로 코드가 실행된다는 걸 보장 할 수 없다는 것이다. 우리는 setTimeout에 대해서 알아보면서 그 원리를 알아보았다. 또한 단일 스레드란, call stack이 1개라는 의미이다. 만약 call stack이 2개라면, 비동기를 보장하지 않을 수 있다. 이러한 원리는 단일 스레드이기 때문에 가능하다.