728x90

Object를 생성할 때마다, 뭔지 모르게 항상 붙는 __proto__가 있다.
또한 출처를 알 수 없는 .length, split(), toString()를 우리는 항상 사용해 왔다.
이것들은 뭘까? 어디서 왔고? 어디서 생겼을까? 라는 생각으로 시작하면 될 것 같다.

먼저, JavaScript는 객체지향 언어다.
하지만, Java, Python과 다르게 class기반의 객체지향 언어가 아니고, prototype 기반의 객제지향 언어다.
(ES5 이후 class를 지원하지만, class를 객체지향의 기반으로 사용하고 있지 않다)

생성자로 사용하기 위한 fuction을 작성해보자.

Bird constructor, Bird prototype

위 결과를 보면 함수를 생성했는데, constructor__proto__가 함께 생성된 것을 볼 수 있다.

간단히 말하자면, constructor해당 Object의 원본(Bird 자신)을 가리키며, __proto__ Object prototype을 가리킨다.
Object prototype은 JavaScript에서 생성되는 모든 것들의 조상이라고 생각하면 된다
(앞서 말한 toString(), split() 등 모든 built-in method를 가지고 있다)

위 생성자를 이용해 bird1과 bird2를 instance로 찍어보자.

bird1, bird2 Instance

bird1를 출력해보면 자신만의 name, color와 생성자가 가지고 있던 sing function 그리고 __proto__가 생성된 것을 볼 수 있다.
그리고 __proto__를 누르면 function 생성자를 선언할 때 볼 수 있던 constructor__proto__다시 볼 수 있다.

이런식으로, prototype chain을 통해 연속적으로 자신의 조상 prototype을 참조한다.

즉, 우리가 JavaScript안에서 생성하는 Array, String, Object, function 등 모두 함수를 통해 생성되며,
단순히 하나의 Object만 생성되는 것이 아니라, constructor와 Object prototype을 참조하며 생성된다.
또한, 각 instance마다 property를 추가할 필요 없이 prototype을 이용해 memory를 공유할 수 있다.

참고 자료 https://dev.to/lydiahallie/javascript-visualized-prototypal-inheritance-47co

 

🎉👨‍👩‍👧‍👧 JavaScript Visualized: Prototypal Inheritance

 

dev.to

 

728x90

✨ JavaScript에서 Hoisting이란, 변수 또는 함수 사용을 선언 전에 할 수 있다는 것(?)이다.

w3schools에서는 변수나 함수 선언부를 코드 최상위에 위치시키는 것이라고 말하고 있으며,
MDN에서는 위의 말처럼 가르치고 있지만, 실제로는 그렇지 않다고 한다.

https://www.w3schools.com/js/js_hoisting.asp

 

JavaScript Hoisting

JavaScript Hoisting Hoisting is JavaScript's default behavior of moving declarations to the top. JavaScript Declarations are Hoisted In JavaScript, a variable can be declared after it has been used. In other words; a variable can be used before it has been

www.w3schools.com

https://developer.mozilla.org/en-US/docs/Glossary/Hoisting

 

Hoisting

Hoisting is a term you will not find used in any normative specification prose prior to ECMAScript® 2015 Language Specification. Hoisting was thought up as a general way of thinking about how execution contexts (specifically the creation and execution phas

developer.mozilla.org

📢 예제 1(변수 - var)

예제 1(변수 var)

위의 코드처럼 할당(assign)을 먼저 하고, 실행 한 후, 선언(declare)을 해줘도 문제 없이 작동한다.

예제 1 결과

위 화면을 보면 문제 없이 7이 출력된 것을 볼 수 있다.

📢 예제 2(함수 - function)

이번에는 함수를 위와 같은 방식으로 실행해 보겠다.

예제 2(함수 function)

위 코드처럼 실행을 먼저 해주고, 나중에 선언을 해줘도 문제 없이 작동한다.

예제 2 결과

위 화면을 보면 문제 없이 'Hello'가 출력된 것을 볼 수 있다.

ES2015전에 정확히 명시된 문서는 없지만, ES2015에서 Hoisting을 정의하고 있다.
어렵게 생각하지 말고, 선언부를 코드 최상위로 끌어올린다고 생각하면 될 것 같다.
사실 위처럼 곤란한 상황은 var과 function을 사용해서 생기는 문제다.

위의 문제로 머리가 복잡해지기 싫다면 ES2015의 const와 let을 사용해주면 된다.
(function은 const functionName = () => {}로 사용)
그럼 debugging이 훨씬 수월할 것이다.

결론적으로

hoist의 사전적 정의

선언부를 코드 최상위로 '끌어올린다'라고 생각해주면 되고, 해당 버그를 방지하기 위해 const와 let을 사용하자!

728x90

✨ 평소 DOM을 이용해 Event를 작성하곤 한다. 그 이벤트는 어떻게 관리될까? class를 이용해서 event library를 만들어보자.

1. Button을 click하면 'Hi there!'이라고 consol에서 출력되도록 작성해보자.
2. 브라우저(html file)를 열자마자 자동으로 button을 click하는 trigger를 발생시켜보자
3. button의 click event를 제거해보자

아래 HTML파일 script tag 부분에 작성하면 된다.

<head>
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha256-k2WSCIexGzOj3Euiig+TlR8gA0EmPjuc79OEeY5L45g=" crossorigin="anonymous"></script>
</head>
<body>
<h1>Click the button</h1>
<button>Me!</button>
<script>
여기에 작성
</script>
</body>

편의상 jQuery로 작성해보겠다.

<head>
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha256-k2WSCIexGzOj3Euiig+TlR8gA0EmPjuc79OEeY5L45g=" crossorigin="anonymous"></script>
</head>
<body>
<h1>Click the button</h1>
<button>Me!</button>
<script>
$('button').on('click', () => {
console.log('Hello');
});
 
$('button').trigger('click');
 
$('button').off('click');
</script>
</body>


.on으로 click event를 등록하고, .trigger로 click event를 자동 실행하고, .off로 click event를 제거하였다.

이 event들은 어떻게 관리될까? class를 이용해서 event를 관리하는 library를 작성해보자

Event Library class

class를 이용해 event library를 작성하면 위와 같이 작성할 수 있다.

생성자(constructor)를 이용해 object(map)을 선언해주고, on(), trigger(), off() method를 실행하며
각 event(key)마다 callback(value)을 넣어주면 된다.
또한, callback은 여러 개가 들어갈 수 있으므로 배열로 선언해주면 된다.

on()은 이벤트 등록을 위한 기능이므로, 해당 event가 있다면 push, 없다면 새로 key를 등록해준다.

trigger()는 이벤트를 실행시켜주므로, for...of를 이용해 obj안에 등록되어 있는 해당 event를 ()를 통해 실행시켜준다.

off()는 이벤트를 제거해주므로, delete를 이용해 obj안에 등록되어 있는 해당 event를 제거해주면 된다.

우리는 평소 사용 방법만 알면 event를 쉽게 등록하고 사용하거나 제거할 수 있다.
하지만, 우리 눈에 보이지 않는 event는 어떻게 관리되는 지 위의 내용을 통해 조금이나마 이해할 수 있다.

추가) Vanilla JavaScript로 작성했을 때,

<head>
<script
src="https://code.jquery.com/jquery-3.2.1.slim.min.js"
integrity="sha256-k2WSCIexGzOj3Euiig+TlR8gA0EmPjuc79OEeY5L45g="
crossorigin="anonymous"
></script>
</head>
<body>
<h1>Click the button</h1>
<button>Me!</button>
<script>
// Vanilla JavaScript
const btn = document.querySelector('button');
 
function handleClickEvent() {
console.log('Hi there!');
}
 
btn.addEventListener('click', handleClickEvent);
 
btn.click();
 
btn.removeEventListener('click', handleClickEvent);
</script>
</body>

+ Recent posts