Javascript 및 웹 개발에서 백과사전과도 같은 MDN을 요약 정리해놓은 문서
Ref
- MDN
- The standards for JavaScript are the ECMAScript Language Specification (ECMA-262) and the ECMAScript Internationalization API specification (ECMA-402).
What is Javascript
JavaScript (JS) is a lightweight, interpreted, or just-in-time compiled programming language with first-class functions.
- first-class functions: 변수처럼 사용될 수 있는 함수. Argument로 넘긴는 등
JavaScript is a prototype-based, multi-paradigm, single-threaded, dynamic language, supporting object-oriented, imperative, and declarative (e.g. functional programming) styles.
- Prototype-based programming: Class의 명시적 선언 없이, 인스턴스에 property와 method를 선언하여 class를 만드는 방식
Compiling and Linking
Compilation
Programming Language를 Machine Language로 변환하는 과정
<filename>.o or <filename>.obj 파일 생성: machine language file
에러 형식: a missing semicolon, an extra parenthesis
Linking
각각 떨어져 있는 machine language file 을 OS가 실행할 수 있는 하나의 Executable File로 묶는 과정
에러 형식: missing or multiple definitions
Compilation phase와 Linking phase를 분리하는 이유
파일 변경 시 매번 전체 파일을 Compilation 하는 건 비효율적임. 수정된 파일만 Compilation 혹은 Linking 하여 효율성을 높인다. IDE에서 대체적으로 잘 제공해주는 기능
JIT Compilation (Just-in-time)
compilation during execution of a program (at run time)
JIT compilation is a combination of the two traditional approaches to translation to machine code—ahead-of-time compilation (AOT), and interpretation - and combines some advantages and drawbacks of both.
- AOT: 런타임 이전에 컴파일 하는 방법
- Interpreter
- Parse the source code and perform its behavior directly
- Translate source code into some efficient intermediate representation or object code and immediately execute that
Compiled 코드는 속도가 높다 + interpretation은 유연성이 높다
JIT compilation is a form of dynamic compilation, and allows adaptive optimization such as dynamic recompilation and microarchitecturespecific speedups.
Fundamental
JS를 활용하여 브라우저의 APIs를 활용할 수 있다. APIs
- DOM API, Geolocation API, Canvas & WebGL, Audio & Video API (HTMLMediaElement & WebRTC)
JS의 실행환경은 브라우저의 탭이다 ← Execution environments : 각 탭은 완전히 독립 환경을 가지고 있다. ← 보안에 좋음
JS의 실행 순저는 Top-bottom 따라서, 순서가 중요함
JS는 Interpreted programming 언어 (the code is run from top to bottom and the result of running the code is immediately returned. You don't have to transform the code into a different form before the browser runs it. The code is received in its programmer-friendly text form and processed directly from that.) 이지만 대부분의 모던 JS 인터프리터는 perfomance를 높이기 위해 just-in-time compiling 테크닉을 활용한다. (JavaScript 소스 코드는 스크립트가 사용되는 동안 더 빠른 바이너리 형식으로 컴파일되어 최대한 빨리 실행할 수 있습니다. 그러나 JavaScript는 컴파일이 미리 처리되지 않고 런타임에 처리되기 때문에 여전히 Interpreted 언어로 간주됩니다.)
Dynamic in client-side: 실시간으로 새로운 HTML table이나 서버로 부터 오는 data를 feeded되는 것을 말한. Static과 반대
DOM이 Parsing 되기 전 js가 수행되는 오류를 방지하기 위해
- Internal:
document.addEventListener("DOMContentLoaded", function() {
.. - external:
<script src="script.js" defer></script>
- </body> tag 전으로 js코드를 뒤에 배치할 순 있지만, 그 동안 js가 완전히 block 되기 때문에 js의 loading/parsing 측면에서 performance issue 가 있을 수 있다.
- Internal:
async & defer
- async - execution순서를 보장 X. 각 스크립트가 독립적일 경우 / defer - html이 모두 파싱된 이후 ⇒ DOM이나 순서에 영향을 받을 script라면 필요
Basic Syntax
- var: Back when JavaScript was first created, this was the only way to declare variables. The design of
var
is confusing and error-prone. Solet
was created in modern versions of JavaScript, a new keyword for creating variables that works somewhat differently tovar
, fixing its issues in the process.- Hoisting: 모든 선언문을 위로 끌어올리는 행위
- you can declare the same variable as many times as you like
- template literal:
- use backtick characters (```)
const greeting =
Hello, ${name};
- Template literals respect the line breaks in the source code. To have the equivalent output using a normal string you'd have to include line break characters (
\\n
) in the string
- use backtick characters (```)
- basic array methods
- indexOf, push, pop, shift, unshift, splice, filter, map, split, join ..
- Looping method
- Function Call
- btn.onclick = displayMessage; ← 클릭했을 때 함수 호출
- btn.onclick = displayMessage(); ← 선언시 바로 함수 호출
- event: 특정 상황에 수행되는 매커니즘 ex) onClick, onLoad
When such a block of code is defined to run in response to an event, we say we are registering an event handler. Note: Event handlers are sometimes called event listeners - 사실 js에서 처리하는거이 아니라 브라우저 api에서 처리하는 것 or Nodejs Event Model
The modern mechanism for adding event handlers is the
[addEventListener()](<https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener>)
method. rather then Event handler properties ← bad practicecounter part & abort
btn.addEventListener('click', bgChange, { signal: controller.signal });
controller.abort();
btn.removeEventListener('click', bgChange);
multi register
myElement.addEventListener('click', functionA); myElement.addEventListener('click', functionB);
event object
function bgChange(e) {e.target.style.backgroundColor = rndCol;}
- e.target : 이벤트가 발생한 html element를 가리킨다
e.preventDefault()
: default 이벤트 block - linkBubbling and capturing
- capturing: onclick 이벤트가 <html> 태그 부터 밖에서 안으로 전부 수행
- target: 클릭한 해당 element의 onclick만 수행
- bubbling: 클릭한 target element에서부터 <html> 까지 밖으로 전부 onclick 수행
- In modern browsers, by default, all event handlers are registered for the bubbling phase.
e.stopPropagation();
- Event delegation
- arrow functions
() => x
is valid shorthand for() => { return x; }
.
Object
object literal — we've literally written out the object contents as we've come to create it. This is in contrast to objects instantiated from classes
const person = { name: 'Bob', age: 32, greeting: function() { alert('Hi! I\\'m ' + [this.name](<http://this.name/>) + '.'); } };
dot notation === bracket notation →
person.name.first
===person['name']['first']
- bracket notation: dynamic member name →
person[myDataName] = myDataValue;
- bracket notation: dynamic member name →
this: he
this
keyword refers to the current object the code is being written inside → context change 에 대응할 수 있음bult-in objects: Array, Math 등.. 그러나 built-in object가 항상 자동으로 instance 를 만드는건 아님. 예를들면, Notification의 경우 필요할때 new object를 만듬
constructor function: define and initialize objects and their features - normal function의 shortcut 개념. object를 선언하고 return 할 필요가 없다.
function Person(name) { // constructor function usually start with Capital letter [this.name](<http://this.name/>) = name; this.greeting = function() { alert('Hi! I\\'m ' + [this.name](<http://this.name/>) + '.'); }; } const instance = new Person('Paul')
Object() constructor
let person1 = new Object({ name: 'Chris', age: 38, greeting: function() { alert('Hi! I\\'m ' + [this.name](<http://this.name/>) + '.'); } });
create() method: using an existing object as the prototype of the newly created object.
let person2 = Object.create(person1);Object.getPrototypeOf(obj).
Prototype
- Prototypes are the mechanism by which JavaScript objects inherit features from one another. JavaScript is often described as a prototype-based language
- Prototype chain: 아래에서 부터 해당 property 가 있는지 체크하고 없으면 그 위로, 그 위로
access to prototype
- proto: deprecated before ECMA2015
Object.getPrototypeOf(obj)
: new access
- Object.prototype. : inherit 시키려는 property
- Object. : Object 자체에서만 쓸 수 있는 property
create() Object
- let person2 = Object.create(person1); ← person1을 prototype으로 Object를 생성
- person2.proto ← return person1 Object
constructor property
person1.constructor
← return Person()person2.constructor
← return Person()
modifying prototypes: methods added to the prototype are then available on all object instances created from the constructor
Person.prototype.farewell = function() { alert(this.name.first + ' has left the building. Bye for now!'); };
- performing
delete person1.__proto__.farewell
ordelete Person.prototype.farewell
would remove thefarewell()
method from allPerson
instances.
- performing
Inheritance
- call function: This function basically allows you to call a function defined somewhere else, but in the current context
function Teacher(first, last, age, gender, interests, subject) { Person.call(this, first, last, age, gender, interests); this.subject = subject; }
using JSON: js object와 형식이 유사하나, string의 경우 큰 따옴표로 써야함. 네트워크 통신에 유리한 구조. JSON.parse , JSON.stringify 활용
request.open('GET', requestURL); request.responseType = 'text'; // now we're getting a string! request.send();
request.onload = function() { var superHeroesText = request.response; // get the string from the response var superHeroes = JSON.parse(superHeroesText); // convert it to an object populateHeader(superHeroes); showHeroes(superHeroes); }
Object.assign():
Object.assign()
메서드는 출처 객체들의 모든 열거 가능한 자체 속성을 복사해 대상 객체에 붙여넣습니다. 그 후 대상 객체를 반환합니다.
const target = { a: 1, b: 2 };
const source = { b: 4, c: 5 };
const returnedTarget = Object.assign(target, source);
console.log(target);
// expected output: Object { a: 1, b: 4, c: 5 }
console.log(returnedTarget);
// expected output: Object { a: 1, b: 4, c: 5 }
- Object.call():
call()
메소드는 주어진this
값 및 각각 전달된 인수와 함께 함수를 호출합니다
function Product(name, price) {
[this.name](<http://this.name/>) = name;
this.price = price;
}
function Food(name, price) {
Product.call(this, name, price);
this.category = 'food';
}
console.log(new Food('cheese', 5).name);
// expected output: "cheese"
Async
The answer is because JavaScript, generally speaking, is single-threaded
Thread: Each thread can only do a single task at once
- javascript는 main thread 하나로만 구성될 수 있음, 하지만 Web worker 등의 툴을 통해서 worker thread를 활용할 수 있음
Main thread: Task A --> Task C Worker thread: Expensive task B
- 하지만 web worker는 두가지 문제점이 존재
- DOM에 직접 접근할 수 없음
- 언제 끝나는지 정확한 시점을 알 수 없음
There are two main types of asynchronous code style you'll come across in JavaScript code, old-style callbacks and newer promise-style code
- Async callback: call back function을 argument로 넘겨주는 것
- Promises: Promises are the new style of async code that you'll see used in modern Web APIs
- chain으로 연결 가능, 순서 보장, 에러 핸들링
event queue: async operation이 호출되면 곧바로 event queue로 넘어가서 main thread가 끝난 후에 실행되어, 결과를 js에 다시 넘겨준다
Promise
- a Promise is an object that represents an intermediate state of an operation
- Promise 가 끝난 후 결과 처리를 보장한다.
- Running code in response to multiple promises fulfilling:
Promise.all([a, b, c]).then()
- Building custom promises
let timeoutPromise = new Promise((resolve, reject) => { setTimeout(() => { resolve('Success!'); }, 2000); });
Async: Invoking the async function now returns a promise
let hello = async function() { return "Hello" };
Await:
await
only works inside async functionsawait
can be put in front of any async promise-based function to pause your code on that line until the promise fulfills, then return the resulting value.- error handling: You can use a synchronous
[try...catch](<https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/try...catch>)
structure withasync
/await
중급
고급
프로토타입 메소드 상속
- prototype chain: 속성이나 메소드를 해당 instance에서 못찾으면 prototype에서 찾고 없으면 다시 그 prototype에서 찾는다.window.Object.prototype까지 찾았는데도 없다면 undefined를 출력
var o = {
a: 2,
m: function(b){
return this.a + 1;
}
};
console.log(o.m()); // 3
// o.m을 호출하면 'this' 는 o를 가리킨다.
var p = Object.create(o);
// p 는 프로토타입을 o로 가지는 오브젝트이다.
p.a = 12; // p 에 'a'라는 새로운 속성을 만들었다.
console.log(p.m()); // 13
// p.m이 호출 될 때 'this' 는 'p'를 가리킨다.
객체 생성 방법
var o = {a: 1};
// o 객체는 프로토타입으로 Object.prototype 을 가진다.
// 이로 인해 o.hasOwnProperty('a') 같은 코드를 사용할 수 있다.
// hasOwnProperty 라는 속성은 Object.prototype 의 속성이다.
// Object.prototype 의 프로토타입은 null 이다.
// o ---> Object.prototype ---> null
var a = ["yo", "whadup", "?"];
// Array.prototype을 상속받은 배열도 마찬가지다.
// (이번에는 indexOf, forEach 등의 메소드를 가진다)
// 프로토타입 체인은 다음과 같다.
// a ---> Array.prototype ---> Object.prototype ---> null
function f(){
return 2;
}
// 함수는 Function.prototype 을 상속받는다.
// (이 프로토타입은 call, bind 같은 메소드를 가진다)
// f ---> Function.prototype ---> Object.prototype ---> null
var b = Object.create(a); // only for ECMAScript 2015
// b ---> a ---> Object.prototype ---> null
Class 키워드 - only for ECMAScript 2015
'use strict';
class Polygon {
constructor(height, width) {
this.height = height;
this.width = width;
}
}
class Square extends Polygon {
constructor(sideLength) {
super(sideLength, sideLength);
}
get area() {
return this.height * this.width;
}
set sideLength(newLength) {
this.height = newLength;
this.width = newLength;
}
}
var square = new Square(2);
// square ---> Square ----> Polygon ----> Object.prototype ---> null
프로토타입 상속의 종류
- 위임형 상속: 메소드를 위임 상속할 경우 모든 객체가 각 메소드에에 대해 하나의 코드를 공유하므로 메모리를 절약할 수 있다. 일반적 상속
class Greeter {
constructor (name) {
[this.name](<http://this.name/>) = name || 'John Doe';
}
hello () {
return Hello, my name is ${ this.name };
}
const george = new Greeter('George');
const msg = george.hello();
console.log(msg); // Hello, my name is George
- 연결형 상속: 연결형 상속은 한 객체의 속성을 다른 객체에 모두 복사함으로써 상속을 구현하는 방법이다.이 상속법은 Javascript 객체의 동적 확장성을 이용한 방법이다. 객체 복사는 속성의 초기값을 저장하기 위한 좋은 방법이다.
const proto = {
hello: function hello() {
return Hello, my name is ${ this.name };
}
};
const george = Object.assign({}, proto, {name: 'George'});
const msg = george.hello();
console.log(msg); // Hello, my name is George
엄격모드 'use strict'
엄격 모드는 평범한 JavaScript 시멘틱스에 몇가지 변경이 일어나게 합니다.
- 기존에는 조용히 무시되던 에러들을 throwing합니다.
- JavaScript 엔진의 최적화 작업을 어렵게 만드는 실수들을 바로잡습니다. 가끔씩 엄격 모드의 코드는 비-엄격 모드의 동일한 코드보다 더 빨리 작동하도록 만들어집니다.
- 엄격 모드는 ECMAScript의 차기 버전들에서 정의 될 문법을 금지합니다.
Typed Array
빠르고 쉽게 형식화 배열의 원시 이진 데이터를 조작할 수 있게 하는 것
메모리 관리
Concurrency model & Event Loop
- Stack: 함수 호출 코드실행 스택
function foo(b) {
var a = 10;
return a + b + 11;
}
function bar(x) {
var y = 3;
return foo(x * y);
}
console.log(bar(7)); //returns 42
- Heap: 객체들이 저장되는 영역. 구조화되지 않은 넓은 영역
- Queue: JavaScript 런타임은 처리 할 메시지 목록 인 메시지 대기열을 사용합니다. 각 메시지에는 메시지를 처리하기 위해 호출되는 관련 함수가 있습니다. 런타임은 대기열에서 가장 오래된 메시지부터 처리하기 시작합니다. 그렇게하기 위해, 메시지는 큐에서 제거되고 해당 기능이 메시지를 입력 매개 변수로 호출됩니다. 언제나 그렇듯이, 함수를 호출하면 그 함수의 사용을위한 새로운 스택 프레임이 생성됩니다.
- Event Loop: 웹 브라우저에서 이벤트 리스너가 부착된 이벤트가 발생할 때마다 메시지가 추가됩니다. 리스너가 없으면 이벤트는 손실됩니다. 클릭 이벤트 핸들러가 있는 요소를 클릭하면 다른 이벤트와 마찬가지로 메시지가 추가됩니다.
while(queue.waitForMessage()){
queue.processNextMessage();
}