All Articles

Javascript

Javascript Prototype

  • 자바스크립트는 프로토타입 기반 언어로 객체 지향 프로그래밍의 한 형태로 클래스가 없고, 클래스 기반 언어에서 상속을 사용하는 것과 다르게, 객체를 프로토타입으로 하여 복제의 과정을 통하여 객체의 동작 방식을 다시 사용할 수 있다.
  • 자바스크립트의 모든 객체는 자신의 부모를 가리키는 참조 링크인 prototype link 가 존재한다. 객체의 prototype 은 부모의 프로토타입 객체를 바라보며, 이 것이 반복되다가, 프로토타입으로 null 을 가지고 있는 객체에서 끝이 난다.
  • 자바스크립트의 모든 객체는 자신의 프로토타입으로부터 Constructor 프로퍼티를 상속한다. 객체 인스턴스가 생성되는 순간 프로토타입의 Constructor 생성자 메서드를 호출한다. 또한 모든 자바스크립트 함수는 function protoype 객체를 호출하기 때문에 function prototype 객체의 콘스트럭처를 호출하여 생성한다.
  • 순수 원시값은 prototype 이 존재하지 않는다. 하지만 원시값을 읽을 때 래퍼 타입이 생성되어, 해당 객체의 protoype 을 사용할 수 있다. 원시값 호출 시 래퍼 타입 객체를 생성하고 읽은 후에는 래퍼 타입 객체를 제거한다.
  • 거의 모든 객체는 Object.prototype 을 상속하기 때문에, Object.prototype 에 추가되어 있는 메서드를 사용할 수 있다.
  • 자바스크립트는 순수원시값을 제외한 모든 것이 객체입니다. 객체를 생성하면 공용 헛간이라고 할 수 있는 프로토타입 객체가 생성되고 그 곳간에는 우리가 자주 사용하는 toString() 과 같은 빌트 인 프로퍼티들을 접근할 수 있는 링크인 __proto__ 라는 prototype link 가지고 있다. 이렇게 찾을 수 있는 방법은 __proto__ 를 이용해 자신을 만들어낸 원형을 의미하는 프로토타입 객체를 참조하기 때문에 Constructor 와 많은 프로퍼티들을 가져와 사용할 수 있다.
  • new operator 를 사용해 생성한 객체에서 메소드와 프로토타입으로 정의한 메소드 명이 같다면 객체 직속으로 해당 메소드를 가지고 있는지 찾아본다. 우리가 농사를 지을 때, 자기 자신의 헛간부터 찾아보고 없으면 공용 헛간(프로토타입 객체)을 이용하듯, 공용 헛간에도 없다면 그 다음은 지자체 헛간, 나라 헛간까지 찾아보고 없다(null)면 없는거다.(undefined)

Event Loop

  • setTimeout 함수나 XMLHttpRequest 는 자바스크립트 엔진이 아닌 Web API 영역에서 대기 후 태스크 큐로 들어간다. 그 후 대기하고 있다가 콜 스택이 비워지면 테스크 큐에서 함수를 하나씩 호출 스택으로 밀어 올리고 태스크 큐에 새로운 함수가 들어올 때까지 대기한다.
  • 콜 스택이 차 있는 상태에서는 렌더링을 할 수 없다. 렌더도 하나의 콜백처럼 행동하며 스택이 비워질 때까지 기다려야 하며, 보통의 콜백보다는 더 높은 우선순위를 가진다. 콜 스택에 동기식 루프가 진행되는 동안은 렌더도 막히게 되어 다른 행동이 불가능하다. 그렇기 때문에 비동기 루프를 통해 큐에 쌓고, 렌더가 끼어들 기회를 주는 방식으로 처리한다.
  • 비동기 방식으로 호출한 함수는 동기적 방식으로 호출한 함수들이 끝나면, 차례대로 처리된다.

Obfuscation, Minify(Uglify)

  • 자바스크립트 코드 자체를 분석하기 어렵게 만드는 과정
  • 사용자가 웹사이트에 접근하게 되면 해당 스크립트를 그대로 볼 수 있게 됩니다. 이를 방지하고자 적용하는 기법이 바로 난독화입니다. 난독화는 자바스크립트 이외에도 사용할 수 있습니다.
  • 대중적으로 사용하는 것이 uglify.js 와 구글 Closure Compiler 를 사용합니다. 난독화를 적용하면 해석하기 까다로워지고파일 자체가 압축되는 효과도 볼 수 있습니다.
  • 전송해야할 파일의 용량이 줄어들면 사용자입장에서는 더 빠르게 로딩할 수 있고 서버측에서는 트래픽이 줄어들기 때문에 많은 이점을 가질 수 있다.
  • sql injection - 자바스크립트코드를 iframe 및 javascript 를 삽입해 악성코드 웹해킹하는 방법

Memory Structure

  • 메모리는 크게 코드, 데이터, 힙, 스택 영역으로 나뉜다.
  • 코드 영역은 우리가 적은 코드가 적재되는 영역이다. 컴파일이 끝난 기계어로 들어간다.
  • 데이터 영역은 전역 변수 static 변수들이 적재되는 곳이다. 프로그램이 끝날 때까지 존재한다.
  • 스택 영역은 지역 변수, 매개 변수들이 저장되는데 함수 호출 시 사용되고 끝나면 반환한다. 함수가 호출될 때 그 메모리가 할당된다고 콜 스택이라고 불린다. 컴파일 시 크기가 결정된다.
  • 힙 영역은 메모리가 동적으로 할당되는 곳이다. 런 타임 시에 크기가 결정된다. object, string, 클로저와 같은 레퍼런스 타입을 저장한다. 메모리 크기는 1~8MB 이다.
  • 힙과 스택이 서로 자라나는 방향이 마주보게 된다면 공유 라이브러리 영역의 메모리를 참조하는 곳이 가까워져서 효율적이라고 한다.
  • 스택은 무한 재귀함수가 일어나지 않는 이상 오버플로우가 일어날 일이 거의 없다고 한다.
  • 스택영역에서 사용되는 메모리의 경우 그 데이터의 크기가 크게 영향을 끼치지 않는다고 한다. 데이터는 힙 메모리 영역에 할당되고 그 포인터만 스택으로 가져와서 연산을 하기 때문이라고 한다.
  • 프로그래밍에서 메모리 관리는 메모리 할당메모리 사용메모리 해제 순으로 진행된다.
  • 자바스크립트는 프로토타입 기반 언어이고 타입 또한 동적으로 바뀔 수 있다.
  • 배열은 길이와 타입이 정해져 있지 않고, 객체는 동적으로 데이터를 할당할 수 있다. 그렇기에 자바스크립트는 모든 객체를 키 밸류로 메모리를 저장한다.
  • 메모리 검색 속도가 다른 언어들보다 느리기에 V8 엔진은 인라이닝과 히든클래스 기법을 사용한다.

    • 인라이닝은 함수 호출 부분을 함수로 치환하는 방법이다.
    function test() {
    a + b;
    }
    
    // test 함수를 호출하면 a+b 로 대체된다.
    test(); // -> a+b
    • 히든 클래스는 자바스크립트가 클래스처럼 멤버에 접근 할 수 있게 해주는 장치이다.
  • Garbage Collection

    • 고수준의 언어는 가비지 컬렉터가 있으며 이 것의 역할은 메모리 할당을 추적하고 언제 할당된 메모리가 더 이상 사용되지 않는지 파악해서 자동으로 반환하는 것입니다.
    • 살아있는 오브젝트를 찾아내기 위해서는 GC가 포인터를 따라갈 수 있어야 한다. 이를 위해 V8은 Tagged pointer를 사용한다. 데이터 끝에 약간의 비트를 마련하고 여기에 포인터인지 데이터인지 태깅하는 방식이다.
    • Reference-counting 가비지 콜렉션

      • 객체가 가리키는 참조가 하나도 없는 경우 가비지컬렉션 대상으로 간주합니다.
      • 한계: 순환참조
    • Mark-and-sweep 알고리즘

      • 주기적으로 가비지 콜렉터는 roots로 부터 시작하여 roots가 참조하는 오브젝트들, roots가 참조하는 오브젝트가 참조하는 오브젝트들… 을 닿을 수 있는 오브젝트라고 표시한다. 그리고 닿을 수 있는 오브젝트가 아닌 닿을 수 없는 오브젝트에 대해 가비지 콜렉션을 수행한다.
  • 메모리 누수 방지법

    • 전역 변수 생성 지양(var, 글로벌 this) → 자바스크립트 파일 상단에 use strict 사용. 불가피한 상황으로 전역변수를 사용한다면 사용 후 null 로 할당하거나 다른 변수로 할당
    • 사용이 끝난 콜백함수들(addEventListener)은 이벤트를 제거(removeEventListener)해 줄 필요없이 순환참조를 탐지하고 적절히 처리하는 가비지 컬렉터를 지원한다고 하지만 의문점이 든다. 정말 필요없는 것인지…
  • Ref