컴파일러는 뭐고 인터프리터는 뭔가요?

 

컴파일러와 인터프리터는 고급언어로 작성된 소스코드를 기계어로 번역한 후에 프로그램을 실행하는 것입니다.

 

이 둘은 아래와 같은 차이점을 가지고 있습니다.

 

컴파일러

파일을 한 번에 번역합니다. 번역후에는 실행파일이 생성됩니다. 

이후의 실행에는 생성된 실행파일을 가지고 실행하게 됩니다.

모든 파일을 한 번에 번역하여야 하므로 번역 과정은 인터프리터에 비해 상대적으로 느리지만 이미 번역된 실행파일을 가지게 되므로 이후의 실행에는 빠릅니다.

 

인터프리터

파일을 한 줄씩 번역을 합니다. 번역하는 시간은 한 줄만 번역을 하므로 짧지만 실행 할때마다 번역을 하여야 하므로 실행 시간이 컴파일러에 비해 느립니다.

실행파일이 생성되지 않으므로 같은 파일을 실행하게 되면 매번 같은 번역 과정을 가져야 합니다.

 

이러한 인터프리터를 사용하는 이유는 하드웨어에 종속되지 않은 환경에서 실행하기 위함입니다.

 

a cpu에서 컴파일러를 통해 생성된 실행 파일은 b cpu에서는 실행되지 않습니다.

이는 실행 파일이 하드웨어의 환경에 맞게 생성되기 때문입니다.

그래서 jvm을 설치하여 a cpu에서 컴파일된 실행파일을 b cpu에서 돌리기 위해 jvm 내부에서 실행하는 과정이 있습니다.

 

 

위의 컴파일러 동작과 다르게 인터프리터는 해당 프로그램을 하드웨어의 환경에 맞게 변환을 합니다.

그래서 a cpu에서 돌아가는 프로그램이 b cpu에서도 문제없이 돌아갈 수 있습니다.

이러한 이유로 인터프리터를 사용하곤 합니다.

 

 

  컴파일러 인터프리터
개발 편의성 코드를 수정하고 컴파일을 매번 다시 해야 한다. 수정후에 즉시 실행 가능
실행 속도 빠르다 ㄴ리다.
보안 코드가 유출되지 않는다. 코드가 유출될 수 있다.
파일 용량 실행 파일 전체를 전송해야 하므로, 용량이 크다. 코드만 전송하면 되므로 용량이 작다.
프로그래밍 언어 c, c++ python, ruby

 

 

 

 

출처 : https://cbw1030.tistory.com/276

 

컴파일러와 인터프리터의 차이점을 알아보자

안녕하세요. 이번 포스팅에서는 컴파일러와 인터프리터에 차이와 장단점에 대해서 알아보겠습니다. 컴파일러와 인터프리터는 사람이 이해할 수 있는 고급언어로 작성된 소스 코드를 기계가 이

cbw1030.tistory.com

https://velog.io/@jaeyunn_15/OS-Compiler-vs-Interpreter

 

[OS] Compiler vs Interpreter

1\. 인터프리터 방식원래 인터프리터의 의미는 고급 언어로 작성된 프로그램을 한줄씩 번역해서 OS에서 인식하는 기계어로 변역하는 역할이다.자바 인터프리터는 JAVAC 명령으로 자바 프로그램을

velog.io

 

728x90

'Frontend > Javascript' 카테고리의 다른 글

Javascript createObjectURL, revokeObjectURL 🤥  (0) 2022.04.01
Javascript custom event 🐕  (0) 2022.04.01
Javascript 함수 => 1급 객체 ❓  (0) 2022.04.01
Javascript event loop  (1) 2022.03.31
Javascript 얕은 복사, 깊은 복사  (0) 2022.03.27

javascript 강의나 책을 보면 1급 객체라는 단어가 종종 나오곤 합니다.

1급 객체가 무엇인지에 대하여 궁금중이 생겨 포스팅 합니다.

 

1급 객체란 컴퓨터 프로그래밍 언어 디자인에서 다른 객체들에 일반적으로 적용 가능한 연산을 모두 지원하는 객체를 가리킵니다.(wiki)

아래의 조건들을 만족하면 1급 객체라 할 수 있습니다

  • 값으로서 반환될 수 있어야 합니다
  • 함수의 인자로 전달될 수 있어야 합니다
  • 배열이나 변수에 담길 수 있어야 합니다

 

javascript에서 원시 타입은 1급 객체에 성립합니다.

var a = 'a'

function sum(a, b) { return a + b}
sum(1,2) // 3

var array = [a, 1, 2, 3]

 

함수 또한 1급 객체에 성립됩니다. 

// 값으로서 반환 될 수 있습니다.
function outerFunc() {
  function innerFunc() {
    console.log("this is innerFunc")
  }
  return innerFunc
}

outerFunc()()

// 함수의 인자로 전달될 수 있습니다.
var test = function(func, a){
  return func(a)
}

test((f) => {console.log(f)}, 1) // 1
test((f) => {console.log(f)}, 4) // 4

// 변수나 배열에 담길 수 있습니다.
var array = [outerFunc()]

 

javascript에서 함수는 1급 객체이기 때문에 아래와 같이 활용할 수 있습니다.

 

1. 고차함수에서 활용

2. 콜백함수에서 활용

 

 

1. 고차함수에서 활용

const sum = (x) => (y) => x + y

const sumFive = sum(5)
sumFive(2) // 7
sumFive(5) // 10

고차함수란 함수를 인자로 받거나 함수를 반환하는 함수를 뜻합니다.

javascript에서 함수는 1급 객체이기 때문에 위와 같이 활용할 수 있습니다.

고차함수를 활용하면 함수의 확장성을 쉽게 다룰수 있습니다.

const sum = (x) => (y) => x + y

const sumFive = sum(5)
sumFive(2) // 7
sumFive(5) // 10

const sumTen = sum(10)
sumTen(2) // 12
sumTen(5) // 17

 

2. 콜백함수로 활용

function debounce(callback, delay) {
  let timer;
  
  
  return (...args) => {
     if(timer) clearTimeout(timer)
     timer = setTimeout(() => callback.apply(this, args), delay)
  }
  
}

debounce(() => {console.log(1)}, 1000)()

function throttle(callback, delay) {
  let timer = null;
  
  return (...args) => {
    if(!timer) {
        timer = setTimeout(() => {
          callback.apply(this, args)
          timer = null
        },delay)
    }
  }
}

throttle(() => {console.log(1)}, 1000)()

위의 예제는 함수를 콜백함수로 활용하는 예제입니다.

debounce 와 throttle을 직접 구현해 보는 것으로 예제를 대신하였습니다.

 

 

 

출처: https://ko.wikipedia.org/wiki/%EC%9D%BC%EA%B8%89_%EA%B0%9D%EC%B2%B4

 

일급 객체 - 위키백과, 우리 모두의 백과사전

컴퓨터 프로그래밍 언어 디자인에서, 일급 객체(영어: first-class object)란 다른 객체들에 일반적으로 적용 가능한 연산을 모두 지원하는 객체를 가리킨다. 보통 함수에 인자로 넘기기, 수정하기,

ko.wikipedia.org

 

728x90

'Frontend > Javascript' 카테고리의 다른 글

Javascript custom event 🐕  (0) 2022.04.01
컴파일러, 인터프리터  (0) 2022.04.01
Javascript event loop  (1) 2022.03.31
Javascript 얕은 복사, 깊은 복사  (0) 2022.03.27
Javascript Polyfill  (0) 2022.03.26

이벤트 루프는 브라우저에 정의되어 있습니다.

이는 whatwg의 명세를 보면 확인할 수 있습니다.

html은 이전에는 단순 마크업 언어에 불과하였지만 현재는 마크업 언어 + web api 들을 지칭합니다.

이전 까지의 단순 마크업 언어에 불과했던 위상에서 벗어나야 한다 생각합니다.

 

html 5로 들어서면서 그래픽 표현, 양방향 통신 등등 많은것들이 가능해졌습니다.(html5을 애플에서 사용하면서 플래시를 배제하였고 이로인해 어도비에서 많은 언론 플레이를 했던걸로 기억합니다.)

html 에 관련한 글은 나중에 포스팅 할 수 있도록 하고 다시 본론으로 돌아오겠습니다.

 

이 글은 Event loop의 모든 것을 다루진 않습니다. 

몇가지 주요한 관점만 살펴보고자 합니다.

 

위는 브라우저에서의 런타임을 나타낸 것입니다.

 

heap: 메모리 할당이 일어나는 영역(객체 등등)

call stack: 코드 실행에 따라 호출 스택이 쌓이는 영역

 

(dom, ajax, timeout, event loop, task queue 등은 런타임 환경이 제공해 줍니다. (브라우저 or node.js))

 

task queue는 web api에 의해 추가되고 콜 스택이 비게 되면 event loop에 의해 콜스택에서 순차적으로 실행이 됩니다.

event loop는 non blocking io를 수행하기 위해서 필수적인 요소 입니다.

 

비동기 수행을 필요로 하는 동작들이 있습니다.

promise, settimeout, setinterval, requestAnimationFrame 등등 열거한 것들은 task queue에 포함되게 되고 순차적으로 실행이 되게 됩니다.

task queue에도 종류가 있고 우선순위가 있습니다.

 

micro task queue > animation frame > macro task queue 가 우선순위 입니다.

promise는 micro task

requestAnimationFrame은 animation frame

setTimeout, setInterval 등은 macro task queue에 위치하게 됩니다.

 

event loop는 아래와 같이 동작하게 됩니다.

1. macro task queue에서 가장 오래된 테스크를 실행합니다.

2. 모든 micro task를 수행합니다.
     micro task queue는 크기가 0이 될때까지 순회합니다. 있으면 실행을 하게 되구요

3. 렌더링 할것이 있으면 처리합니다.

4. micro task queue가 비었다면 다음 macro task queue를 실행합니다.

5. 다시 micro task queue를 확인합니다. 있으면 전부 실행 없으면 macro task queue를 실행합니다.

 

macro task queue는 하나씩 실행하고 micro task queue가 있는지 없는지 확인하고 있으면 queue가 비어질 때까지 실행합니다.

 

따라서 아래와 같은 코드의 실행은 결과처럼 진행이 됩니다.

console.log('script start')

setTimeout(() => console.log('first setTimeout'))

queueMicrotask(() => console.log('micro task queue'))

Promise.resolve('a').then(() => console.log('promise'))

console.log("script middle");

requestAnimationFrame(() => console.log("animation frame"));

console.log("script end");


// script start
// script middle
// script end
// micro task queue
// promise
// animation frame
// first setTimeout

promise는 micro task,

requestAnimationFrame은 animation frame,

setTimeout은 macro task queue에 enque 되기 때문에 우선순위에 따라 위와 같이 실행이 됩니다.

 

javascript 에서는 queueMicrotask 명령어를 통해 micro task queue에 직접 넣어줄 수도 있습니다.

 

 

출처: https://developer.mozilla.org/ko/docs/Web/JavaScript/EventLoop#%EC%9D%B4%EB%B2%A4%ED%8A%B8_%EB%A3%A8%ED%94%84

 

이벤트 루프 - JavaScript | MDN

JavaScript의 런타임 모델은 코드의 실행, 이벤트의 수집과 처리, 큐에 대기 중인 하위 작업을 처리하는 이벤트 루프에 기반하고 있으며, C 또는 Java 등 다른 언어가 가진 모델과는 상당히 다릅니다.

developer.mozilla.org

https://html.spec.whatwg.org/multipage/webappapis.html#concept-task

 

HTML Standard

 

html.spec.whatwg.org

https://developer.mozilla.org/ko/docs/Web/API/HTML_DOM_API/Microtask_guide

 

JavaScript의 queueMicrotask()와 함께 마이크로태스크 사용하기 - Web API | MDN

마이크로태스크는 자신을 생성한 함수 또는 프로그램이 종료됐고 JavaScript 실행 스택이 빈 후에, 그러나 사용자 에이전트가 스크립트 실행 환경을 운용하기 위해 사용하는 이벤트 루프로 통제권

developer.mozilla.org

https://iamsjy17.github.io/javascript/2019/07/20/how-to-works-js.html

 

Songlog

Javascript, Typescript, Angular, React, RxJS, etc.

iamsjy17.github.io

 

728x90

'Frontend > Javascript' 카테고리의 다른 글

컴파일러, 인터프리터  (0) 2022.04.01
Javascript 함수 => 1급 객체 ❓  (0) 2022.04.01
Javascript 얕은 복사, 깊은 복사  (0) 2022.03.27
Javascript Polyfill  (0) 2022.03.26
Javascript strict mode  (0) 2022.03.25

via GIPHY

 

얕은 복사(shallow copy)

 

변수가 가리키는 주소값이 같은 주소 값을 가리킬때 얕은 복사가 이루어진다고 한다.

reference type을 복사할때 얕은 복사가  이루어진다.

const a = { c: 'c' }
const b = a
b.c = 'd'

console.log(a) // { c: 'd' }
console.log(b) // { c: 'd' }
console.log(Object.is(a,b)) // true

 

spread를 통한 복사는 1 depth 까지만 깊은복사가 이루어진다.

const a = { b: { c: 'c' }, e: 'e' }
const b = {...a}

console.log(a) // { b: { c: 'c' }, e: 'e' }
console.log(b) // { b: { c: 'c' }, e: 'e' }


b.e = 'd'
console.log(a) // { b: { c: 'c' }, e: 'e' }
console.log(b) // { b: { c: 'c' }, e: 'd' }

b.b.c = 'z'
console.log(a) // { b: { c: 'z' }, e: 'e' }
console.log(b) // { b: { c: 'z' }, e: 'd' }

위의 코드를 보면 1depth인 e 값을 바꾸면 b의 값만 바뀌지만 

key 값이 b의 c의 값을 바꾸면 a 변수의 값도 바뀌어 버린다.

1 depth 까지만 깊은 복사가 이루어 지는 것이다.

 

Object.assign을 통한 복사 또한 1 depth 까지만 깊은 복사가 이루어진다.

const a = { b: { c: 'c' }, e: 'e' }
const b = Object.assign({}, a)

console.log(a) // { b: { c: 'c' }, e: 'e' }
console.log(b) // { b: { c: 'c' }, e: 'e' }


b.e = 'd'
console.log(a) // { b: { c: 'c' }, e: 'e' }
console.log(b) // { b: { c: 'c' }, e: 'd' }

b.b.c = 'z'
console.log(a) // { b: { c: 'z' }, e: 'e' }
console.log(b) // { b: { c: 'z' }, e: 'd' }

 


깊은 복사(deep copy)

원시 타입의 복사는 기본적으로 깊은 복사이다.

const a = 'a'
const b = a

원시타입을 복사하게 되면 b 변수에는 새로운 주소에 같은 값이 할당된다

 

깊은 복사를 하기 위해서는

 

커스텀 함수를 사용하거나 

const deepCopy = (target, temp) => {
  for (let key in target) {
  	if (typeof target[key] === 'object') {
      deepCopy(target[key], temp[key] = {})
    } else {
      temp[key] = target[key]
    }
  }
  return temp;
}

const a = { b: { c: 'c' }, e: 'e' }
const b = deepCopy(a, {})

console.log(a) // { b: { c: 'c' }, e: 'e' }
console.log(b) // { b: { c: 'c' }, e: 'e' }


b.e = 'd'
console.log(a) // { b: { c: 'c' }, e: 'e' }
console.log(b) // { b: { c: 'c' }, e: 'd' }

b.b.c = 'z'
console.log(a) // { b: { c: 'c' }, e: 'e' }
console.log(b) // { b: { c: 'z' }, e: 'd' }

라이브러리를 사용하거나 (ex. lodash의 deep copy)

 

JSON.parse(Json.Stringify(Object))) 를 사용한다.

const a = { b: { c: 'c' }, e: 'e' }
const b = JSON.parse(JSON.stringify(a))

console.log(a) // { b: { c: 'c' }, e: 'e' }
console.log(b) // { b: { c: 'c' }, e: 'e' }


b.e = 'd'
console.log(a) // { b: { c: 'c' }, e: 'e' }
console.log(b) // { b: { c: 'c' }, e: 'd' }

b.b.c = 'z'
console.log(a) // { b: { c: 'c' }, e: 'e' }
console.log(b) // { b: { c: 'z' }, e: 'd' }
728x90

'Frontend > Javascript' 카테고리의 다른 글

Javascript 함수 => 1급 객체 ❓  (0) 2022.04.01
Javascript event loop  (1) 2022.03.31
Javascript Polyfill  (0) 2022.03.26
Javascript strict mode  (0) 2022.03.25
Javascript 화살표 함수  (0) 2022.03.25

Polyfill(폴리필)은 웹 개발에서 기능을 지원하지 않는 웹 브라우저 상의 기능을 구현하는 코드를 뜻합니다.

 

예를들면 자바스크립트의 최신 스펙에 나온 함수를 사용하여도 웹 브라우저에서는 돌아가지 않을 수 있습니다.

여러 자바스크립트 엔진에서는 자바스크립트의 최신 스펙중 우선순위에 따라 구현할 것이므로 아직 자바스크립트 엔진에 구현이 되어 있지 않을수도 있는 것이죠.

 

폴리필은 다시 정의하면 기존 함수의 동작 방식을 수정하거나, 새롭게 구현한 함수의 스크립트라 할수 있습니다.

 

현재는 바벨과 같은 트랜스 파일러를 이용합니다.

최신 스펙으로 작성된 스크립트 코드를 명시한 버전에 따라 재작성 해줍니다. 

낮은 버전의 자바스크립트 엔진에서도 프로그램이 돌아갈 수 있게 해주어 서비스가 문제없이 제공될 수 있게 해줍니다.

바벨에는 core-js 라이브러리가 탑재되어 es6 이후의 문법들에 폴리필을 이용할 수 있습니다.

 

이때 폴리필이 이용됩니다.

새로운 문법을 낮은 버전에서도 돌아갈 수 있게 하기 위하여 폴리필이 이용되어 집니다.

 

const arr = [1,2,3,4]
console.log(arr.map((el) => el * 2))


// 예시
Array.prototype.customMap = function (callback) {
  const result = []

  for(let el of this) {
    result.push(callback(el))
  }

  return result
}


console.log(arr.customMap((el) => el * 3))

 

 

출처: https://ko.wikipedia.org/wiki 

 

위키백과, 우리 모두의 백과사전

위키백과:대문 위키백과, 우리 모두의 백과사전. 위키백과 우리 모두가 만들어가는 자유 백과사전문서 583,786개와 최근 기여자 2,122명 사랑방 다른 분들과 의견을 교환해봐요! 질문방 지침으로

ko.wikipedia.org

https://polyfill.io/v3/

 

Polyfill.io

Polyfill.io Upgrade the web. Automatically.

polyfill.io

https://ko.javascript.info/polyfills

 

폴리필

 

ko.javascript.info

 

 

728x90

'Frontend > Javascript' 카테고리의 다른 글

Javascript event loop  (1) 2022.03.31
Javascript 얕은 복사, 깊은 복사  (0) 2022.03.27
Javascript strict mode  (0) 2022.03.25
Javascript 화살표 함수  (0) 2022.03.25
Javascript event capturing, bubbling  (0) 2022.03.25

javascript에는 strict mode가 있습니다.

strict mode를 활성화 시키면 평소에는 무시되던 에러들을 발생시키기 시작합니다.

런타임에서 혹시 발생할 수 있는 에러들을 잡아내는데 도움을 줄 수 있습니다.

 

전체 스크립트에 strict mode를 활성화 시키기 위해서는 코드의 최상단에 "use strict"를 추가해주면 됩니다.

"use strict"
console.log('hihi');

아래와 같이 사용하면 부분 함수에 적용할 수 있습니다.

function test() {
    "use strict"
    console.log('hihi')
}

es6의 모듈은 default가 strict mode 입니다.

script type="module"을 사용하면 strict mode가 default로 사용됩니다.

 

몇 가지 예시를 확인해보겠습니다.

 

전역 변수가 의도치 않게 생기는 것을 방지해 줍니다.

"use strict"

// mistypedVariable 변수가 존재한다고 가정

mistypedvariable = 17; // 오타로 인해 ReferenceError를 발생시킵니다.

 

조용히 무시되던 에러들을 throwing 합니다.

"use strict"

// 쓸수 없는 프로퍼티에 할당
var undefined = 5; // TypeError 발생
var NaN = 5;  // TypeError 발생

// 쓸 수 없는 프로퍼티에 할당
var obj1 = {}
Object.defineProperty(obj, 'x', {value: 4, writable: false})
obj1.x = 5; // TypeError 발생

// getter-only 프로퍼티에 할당
var obj2 = { get x() { return 17; } }
obj2.x = 10; // TypeError 발생

// 확장 불가능 객체에 새 프로퍼티 할당
var fixed = {}
Object.preventExtension(fixed); // Object.seal, Object.freeze
fixed.a = 'a'; // TypeError 발생

 

삭제할 수 없는 프로퍼티를 삭제하려 할때 error를 발생시킵니다.

"use strict"
delete Object.prototype // 에러발생

 

전역 this는 strict mode에서 undefined를 반환합니다. (this는 node에서는 global, 브라우저에서는 window)

 

 

 

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Strict_mode

 

Strict mode - JavaScript | MDN

엄격 모드는 평범한 JavaScript 시멘틱스에 몇가지 변경이 일어나게 합니다.

developer.mozilla.org

 

728x90

'Frontend > Javascript' 카테고리의 다른 글

Javascript 얕은 복사, 깊은 복사  (0) 2022.03.27
Javascript Polyfill  (0) 2022.03.26
Javascript 화살표 함수  (0) 2022.03.25
Javascript event capturing, bubbling  (0) 2022.03.25
Javascript Callback, Promise, async, await  (0) 2022.03.22

화살표 함수는 es6에서 등장하였습니다.

화살표 함수의 기본문법은 아래와 같습니다.

() => {}

const test = () => { console.log('hihi') }

 

화살표 함수는 함수 표현식으로 사용하여야 합니다. 익명함수로서만 사용할 수 있기 때문입니다.

fuction test() {
	console.log('hihi')
}

const test = () => { console.log('hihi') }

 

화살표 함수는 this를 가지지 않습니다. 

따라서 화살표 함수 내부에서의 this는 항상 상위 스코프의 this를 가리킵니다.

bind, call, apply를 통하여 화살표 함수의 this를 변경할수가 없습니다.

 

const people = {
    age: 0,
    older() {
    	setTimeout(() => {
        	this.age++;
            console.log(this.age);
        }, 100)
    }
}

const person = {
	age: 0,
    older() {
    	setTimeout(function() {
        	this.age++;
            console.log(this.age);
        }, 100)
    }
}
 
people.older() // 1
person.older() // NaN

화살표 함수는 this를 가지지 않는다고 하였습니다.

위의 실행결과는 1과 NaN을 출력하게 됩니다.

this는 동적으로 binding되게 됩니다.

하지만 화살표 함수에는 this가 없습니다. 그래서 상위 스코프의 this를 참조하게 됩니다. 그래서 people.older()는 1이 출력됩니다.

함수의 스코프는 선언되는 위치에 따라 결정됩니다. 화살표 함수가 선언된 위치의 상위 스코프는 older이고 older의 this는 객체로서 호출되었으므로 people을 가리킵니다.

 

person.older()의 this는 window를 가리킵니다.

일반 함수는 this를 가지고 있고 이 this는 일반함수로서 호출되었을때 전역객체를 가리킵니다. person.older()의 내부함수는 일반함수로서 호출이 되었습니다. 

따라서 이때의 this는 window를 가리킵니다.

 

화살표 함수를 사용하지 말아야 할때가 있습니다.

이 내용이 이 글의 핵심입니다.

 

메소드

객체의 메소드로서 호출했을때 화살표 함수를 사용하면 this는 전역객체를 가리킵니다.

const a = {
	b: 'b',
    c: () => { console.log(this.b)}
}

a.c() // undefined


const a = {
	b: 'b',
    c: function(){ console.log(this.b)}
}
a.c()// b

// 위아래 객체의 c 메서드는 같은 내용입니다. 표기법만 다른것입니다.

const a = {
	b: 'b',
    c() { console.log(this.b)}
}
a.c()// b

 

prototype

프로토타입에 동적으로 메서드를 할당하는 경우에 문제가 발생합니다.

const a = {
	b: 'b',
}

Object.prototype.sayHi = () => console.log(this.b);
a.sayHi() // undefined


const a = {
	b: 'b',
}

Object.prototype.sayHi = function() {console.log(this.b)}
a.sayHi() // 'b'

 

생성자함수

화살표 함수는 생성자 함수로서 사용할 수 없습니다. 

생성자 함수는 prototype 프로퍼티를 가지고 prototype 프로퍼티가 가리키는 프로토타입 객체의 constructor를 사용합니다.

하지만 화살표 함수는 prototype 프로퍼티를 가지고 있지 않습니다.

const Person = () => {};

console.log(Person.hasOwnProperty('prototype')); false

const foo = new Foo(); // error 발생, foo is not a constructor

 

addEventListener 함수의 콜백함수

일반함수로 콜백함수를 정의하게 되면 this는 이벤트 타겟을 가리키게 됩니다. 

화살표 함수로 콜백함수를 정의하게 되면 상위 스코프인 전역스코프의 this를 가리키게 됩니다.

el.addEventListener('click', function(){
	console.log(this) // target을 호출
}); 

el.addEventListener('click', () => {
	console.log(this) // 전역객체를 호출
});

 

 

 

출처: https://poiemaweb.com/es6-arrow-function

728x90

'Frontend > Javascript' 카테고리의 다른 글

Javascript Polyfill  (0) 2022.03.26
Javascript strict mode  (0) 2022.03.25
Javascript event capturing, bubbling  (0) 2022.03.25
Javascript Callback, Promise, async, await  (0) 2022.03.22
Javascript mixins  (0) 2022.03.21

DOM 이벤트는 3개의 단계로 나뉘어집니다.

1. 이벤트 캡쳐링 - 이벤트가 하위 요소로 전파되는 단계 

2. 타깃 - 이벤트가 실제 타깃 요소에 전달되는 단계

3. 이벤트 버블링  - 이벤트가 상위 요소로 전파되는 단계

 

 

위의 그림처럼 나타낼 수 있습니다.

이제 실제로 어떻게 출력되는지 보겠습니다.

const divs = document.querySelectorAll('div');

divs.forEach(div => {
  div.addEventListener(
    "click",
    function () {
      console.log(this.classList);
    },
    { capture: true }
  );
})

위와 같은 코드로 클릭시에 자신의 classList를 출력하게 하였습니다.

capture: true를 통해 캡처링을 활성화 시켰습니다(default는 false)

 

capturing: true

 

default

첫번째 사진은 캡처링을 활용한 것이고 두번째 사진은 버블링을 활용한 것입니다.

캡처링 시에는 first가 먼저 출력되고 버블링 시에는 first가 나중에 출력된 것을 확인할 수 있습니다.

 

 

캡처링을 제어하려면 addEventListener의 세번째 parameter에 true를 넘겨주거나 capture: true 객체를 넘겨주면 됩니다.

el.addEventListener('click', function(){}, {capture: true})
el.addEventListener('click', function(){}, true)

 

버블링을 더이상 하지 않길 원한다면 event.stopPropagation()을 사용하면 됩니다.

const divs = document.querySelectorAll('div');

divs.forEach(div => {
  div.addEventListener(
    "click",
    function (e) {
      e.stopPropagation()
      console.log(this.classList);
    }
  );
})

위 사진은 stopPropagation을 이용해 이벤트의 전달을 막은 것입니다. 

second만 출력한 것을 확인할 수 있습니다.

 

이러한 버블링을 이용하면 이벤트 위임을 통하여 상위 객체에서 더 적은 메모리를 가지고 동작을 제어할 수 있습니다.

핸들러의 더 적은 할당은 메모리 사용의 감소를 뜻하게 됩니다.

 

 

 

 

 

 

 

출처 : https://ko.javascript.info/bubbling-and-capturing

728x90

+ Recent posts