자바스크립의 기본기를 다시 복습하기 위해서 유투브를 이것 저것 보다가
발견한 드림코딩 by 엘리 님이 자바스크립트 기초 강의를 시작하셔서
영상들을 보면서 간단히 정리해보려고 한다.
공부하면서 계속 업데이트할 예정입니다.
1993 Mosaic Web Browser 첫 웹 브라우저 등장
1994 Netscape Navigater 등장 (UI 요소가 좀 더 더해진 브라우저)
1994 Mocha -> LiveScript, Interpreter 등장. 동적인 요소가 추가되기 시작
1995 Javascript 등장!!
1995 Internet Explorer 등장
1997 ECMAScript 1 등장, (Language Specification)
2000 Internet Explorer 시장 점유율 95%
2004 Firefox 브라우저 등장
2004 AJAX (Async Javascript And XML) 도입, jQuery 등장
2008 JIT(Just-in-time compilation)가 포함된 크롬 브라우저 등장
2009 ECMAScript5
2015 ECMAScript6
이제는 jQuery, Dojo 라이브러리 없이 웹 API만드로도 웹 어플리케이션 개발 가능해졌다.
최신 버전의 ECMASCript 을 사용하더라도 최신 브라우저가 아니면 사용할 수 없기때문데Babel(Javascript transcompiler) 를 통해 ES5, 6 로 변환한다.
최근에는 WepAssembly 를 통해 다양한 언어들을 이용하여 웹 어플리케이션을 개발할 수 있다.
Web Application Programming Interface
브라우저가 제공하는 API (ex.console, alert)
console.log("Hello World!");
자바스크립트 공부 사이트 MDN
w3schools 는 공식 사이트는 아님!
async vs defer
head 안에 script 를 포함하는 경우 flow
<head>
<script src="main.js"></script>
</head>
parsing HTML : html 파일을 다운로드 받아 브라우저가 한 줄씩 분석 -> DOM 요소로 변환
blocked (fetching js, executing js) : javascript 파일을 서버에서 다운로드 받고 실행한 뒤 다시 parsing HTML 을 이어서 한다
단점 : js 파일 사이즈가 크고 인터넷이 느리다면 로딩되는 데에 시간이 오래 걸린다
body 끝 부분에 script 를 포함하는 경우 flow
<head>
</head>
<body>
<div></div>
<script src="main.js"></script>
</body>
parsing HTML : HTML 파싱이 끝난 뒤 페이지 로드
fetching js, executing js : 페이지 로드 후 js 파일 다운로드 후 실행
단점 : 사용자가 기본적인 html 의 컨텐츠를 빨리 본다는 장점이 있지만, 자바스크립트에 의존적인 프로젝트라면 역시나 시간이 오래 걸린다.
head + async
<head>
<script async src="main.js"></script>
</head>
parsing HTML (fetching js) : 파싱 중에 async script 를 발견하면 파싱하면서 js 파일을 병렬로 다운로드
block (executing js) : 다운로드 된 js 파일을 실행
parsing HTML : 이어서 HTML 파싱
장점 : 다운로드 받는 시간을 절약
단점 : html 파싱 되기 전에 javascipt 파일에서 DOM 요소를 조작하려고 할 때 아직 html 요소가 정의 되기 전 일 수 있다, html 파싱 중에 block이 되기 때문에 여전히 시간이 오래 걸린다
head + defer
<head>
<script defer src="main.js"></script>
</head>
parsing HTML (fetching js) : html 파싱 중에 병렬로 javascipt 다운로드
executing js : html 파싱 완료 후 js 실행
장점 : 정의한 순서대로 js 파일이 실행되며 시간이 제일 많이 절약됨
순수 바닐라 자바스크립트를 이용할 때는 strict mode 로 개발하는 것을 추천
javascript is very flexible
javasciprt 는 매우 유연한 언어기 때문에 상식적(?)인 프로그래밍이 가능하기 위해서는 엄격모드를 사용하는 게 좋다. 그게 아니면 오타 하나 찾기도 힘들게 될 수도...!
프로그래밍에서 가장 중요한 3가지 : 입력, 연산, 출력 (, 전송)
let name = "nana";
console.log(name); //nana
name = "hello";
console.log(name); //hello
어플리케이션 마다 쓸 수 있는 메모리가 할당된다.
let name -> 메모리에 포인터가 생성이되어 -> nana 가 저장된다.
var
don't ever use this!
let(ES6) 가 생기기 전 유일했던 키워드지만 더이상 사용하지 않길 바란다...
let (read/write)
let name = "name";
es6이후로는 let 으로 변수를 선언하고 있다
Mutable data type : 값이 변경될 수 있는 데이터 타입
const 상수 (read only)
const maxNumber = 5;
Immutable data type : 값을 변경할 수 없는 데이터 타입
faveor immutable data type always for a few reasons
block scope
let globalName = "global name";
{
let name ="nana";
console.log(name)l //nana
console.log(globalName); //global name
}
console.log(name); //""
console.log(globalName); //global name
괄호({}) 밖에서는 블록 안에 변수에 접근할 수 없다
파일 안에 바로 정의하는 변수는 global scope 이라고 한다
글로벌 변수는 어플리케이션이 끝날 때 까지 메모리에 탑재되어 있기 때문에 최소한으로 쓰는 것이 좋다
primitive 원시값
value 자체가 메모리에 저장
single item 을 의미하여 예를 들어 number, string, boolean, null 등
object, box container
오브젝트를 가리키는 reference가 메모리에 저장
single item 을 묶어서 한 단위로 관리하는 값
funtion, first-class function
일급객체 함수, 함수에 파라미터, return 값으로도 함수를 사용 가능
자바스크립트는 타입을 dynamic(동적)으로 결정되기 때문에 타입을 미리 선언해주지 않아도 된다.
data types for number : number (only)
일반 숫자 외 3가지 값이 존재 : infinity, -infinity, NaN
숫자의 범위 -2*53 ~ 2*53
string
const world = "World";
const helloWorld = `Hello ${world}`;
const helloWorld = "Hello " + world;
boolean
false : 0, null, undefined, NaN, ""
true : any other value
null & undefined
let nothing = null; //null
let x; //undefined
x = undefined; //undefined
symbol
create unique identifiers for objects
유일한 식별자를 간주하기 위해 사용
const symbol1 = Symbol("id");
const symbol2 = Symbol("id");
console.log(symbol1 === symbol2); //false
//같은 심볼을 사용하려면 Symbol.for로 심볼 선언
const gsymbol1 = Symbol.for("id");
const gsymbol2 = Symbol.for("id");
console.log(gsymbol1 === gsymbol2); //true
object
const ellie = { name: "ellie", age: 20 };
ellie.name = "nana";
오브젝트는 한번 값을 할당하면 다른 object로 변경이 불가
ellie를 가리키는 포인터는 잠겨있고 그 안의 property 의 값을 변경할 수 있다.
dynamic typing : 동적으로 타입이 결정되는 언어
let text = "hello"; //type: string
text = 1; //type: number
text = "7" + 5; //type: string
text = "8" / "2"; //type : number
자바스크립트는 Runtime에서 타입이 결정되기 때문에 Runtime error 가 발생할 때가 잦음 => 그래서 등장한 TypeScript
String concatenation 문자 결합
console.log("my" + " cat");
console.log("1" + 2);
Numeric operators (+,-,/,x,% ...)
Increment and decrement operators (++/--)
let counter = 2;
const preIncrement = ++counter;
// counter = counter = 1;
// preIncrement = counter;
const postIncrement = counter++;
// postIncrement = counter;
// counter = counter + 1;
Assignment operators
let x = 3;
let y = 6;
x += y; // x = x+ y;
Comparison operators
console.log(10 < 6);
console.log(10 <= 6);
Logical operators (||, &&, !)
1) || (OR)
2) && (AND)
heavy한 operation이 있을 경우 맨 뒤에 넣는 게 좋음!
3) ! (NOT)
Equality
== loose equality, with type conversion
"5" == 5 //true
=== stric equality, no type conversion
"5" === 5 //false
object equality by reference
const silver1 = { name: "silver" };
const silver2 = { name: "silver" };
const silver3 =silver1;
console.log(silver1 == silver2); //false
console.log(silver1 === silver2); //false
console.log(silver1 === silver3); //true
silver1과 silver2 는 각각 다른 레퍼런스를 가리키고 있기 때문에 둘은 다르다.
but, silver1과 silver3은 같은 레퍼런스를 가리키고 있기 때문에 둘은 같다.
Conditional operators: if, else if, else (조건문)
const name = "df";
if (name === "silver") {
console.log("welcome, silver");
} else if (name === "coder") {
console.log("welcome, coder");
} else {
console.log("unknown");
}
Ternary operator: ?
condition ? val1 : val2;
console.log(name === "silver" ? true : false);
연속적으로 사용하게 되면 가독성을 해치기 때문에 간단한 경우만 사용한다.
Switch statement
const browser = "IE";
switch (browser) {
case "IE" :
console.log("go away!");
break;
case "Chrome" :
case "Firefox" :
console.log("love you!");
break;
default:
console.log("same all!");
break;
}
Loops (반복문)
while loop
조건에 맞을 때만 실행하고 싶을 때
do wile loop
블럭을 먼저 실행하고 싶을 때
for loop : for(begin; condition; step)
nested loops (중첩 반복문)
중첩 반복문을 돌리면 bigO가 O(n^2)가 나오기 때문에 좋지 않음
break, continue
//iterate from 0 to 10 and print only even numbers(use continue)
for(let i = 0; i <= 10; i++) {
if(i%2 !== 0) {
continue;
}
console.log(i);
}
//iterate from 0 to 10 and print numbers until reaching 8 (use break)
for(let i = 0; i <= 10; i++) {
if(i>8) {
break;
console.log(i);
}
input x -> Function F -> output (x)
API (Application Programming Interface)를 쓸 때 function name을 보고 추측
함수는 프로그램에서 중요한 빌딩 블록이며 subprogram이라고도 부른다.
Function declaraion 함수선언식
자바스크립트에서 Funtion은 Object 이다. (1급 객체)
naming : doSumthing, command, verb
function name(param1, param2) { body ... return; }
Parameters
primitive parameters : 메모리에 value가 저장되어 있기때문에 값이 그대로 전달
object parameters : 레퍼런스를 전달
Default parameters(ES6)
function showMessage(message, from = "unknown") {
console.log(`${message} by ${from}`);
}
showMesage("Hi!");
Rest parameters (ES6)
function printAll(...args) {
for(const arg of args) {
console.log(arg);
}
}
printAll("dream", coding", "ellie");
let globalMessage = "global";
function printMessage() {
let message = "hello";
console.log(message);
console.log(globalMessage);
function printAnoter() {
console.log(message);
let childMessage = "hello";
console.log(childMessage);
}
}
printMessage();
자바스크립트의 스코프란,
밖에서는 안이 보이지 않고 안에서만 밖을 볼 수 있다.
Return a value
return이 없는 함수는 사실 return undefined
와 같다.
Early return, early exit
//bad
function upgradeUser(user) {
if(user.point > 10) {
//long upgrade logic ...
}
}
//good
function upgradeUser(user) {
if(user.point <= 10) {
return;
}
// long upgrade logic ...
}
Function Expression 함수표현식
//anonymous function
const print = function () {
console.log("print");
}
//named function
const print2 = function print() {
console.log("print2");
}
print(); //print
print2(); //print2
function declaration은 호이스팅이 된다. 즉, 함수 정의하기 전에 호출이 가능하다.
Callback hell
function randomQuiz(answer, printYes, printNo) {
if(answer === "love you") {
printYes();
} else {
printNo();
}
}
const printYes = function () {
console.log("Yes!");
}
//named function -> 디버깅할 때 함수이름을 확인하기 위해
const printNo = function print() {
console.log("No!");
}
randomQuiz("love you", printYes, printNo);
const simplePrint = () => console.log("simplePrint!");
const add = (a,b) => a+b;
함수표현식 보다 더 간결하다.
(function hello() {
console.log("IIFE");
})();
함수를 바로 실행하고 싶을 때 사용하기 좋은 표현식
class : fields(속성), methods(행동)
data class : fields
class => template, declare once, no data in
object => instance of a class, created many times, data in
자바스크립트는 ES6부터 class 가 도입
자바스크립트의 클래스는 기존에 있던 프로토타입이 기반된 syntactic sugar(문법적 설탕)
클래스 선언
class Person {
constructor(name, age) {
//fields
this.name = name;
this.age = age;
}
//methods
speak() {
console.log(`${this.name} : hello!`};
}
}
const silver = new Person("silver", 20);
silver.speak(); //silver : hello!
Getter and setters
class User {
constructor(firstName, lastName, age)
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
}
get age() {
return this._age;
}
set age(value) {
this._age = value < 0 ? 0 : value;
}
}
const user1 = new User("Steve", "Job", -1); //나이가 -1 ? 말이 안됨
getter 와 setter를 정의하게 되면
this.age
는 메모리에 올라가있는 데이터를 읽어오는 게 아니라 getter
를 호출하게 된다.
그리고 this.age = age;
값을 할당할 때 바로 메모리에 값을 할당하는 것이 아니라 setter
를 호출하게 된다.
따라서 getter, setter 안의 변수는 필드와 다르게 사용해야 한다. (ex. _age)
public, private fields
아직 사용하긴 이르지만 최근 추가된 기능 , 브라우저 지원 X
class Experiment {
publicField = 2;
#privateField = 0;
}
static properties and methods
아직 사용하긴 이르지만 최근 추가된 기능 , 브라우저 지원 X
class Article {
static publisher = "Dream coding";
constructor(articleNumber) {
this.articleNumber = articleNumber;
}
static printPublicsher() {
console.log(Article.publisher);
}
}
데이터와 상관없이 인스턴스, 오브젝트에 상관없이 공통적으로 사용하고싶은 데이터가 필요할 때 주로 사용
오브젝트에 할당된 값이 아니라 클래스에 할당된 값
상속 (inheritance)
객체지향프로그래밍의 특징 중 하나로 기존에 정의되어있는 클래스의 필드와 메서드를 물려받아 새로운 클래스를 작성하는 것을 의미한다.
기존에 정의되어있는 클래스를 부모 클래스 라고 한다. 새로운 클래스는 자식 클래스.
상속은 공통된 부분을 클래스로 만들어 코드를 재활용할 수 있다는 점에서 큰 장점을 가지고 있다.
overloading vs overriding
(대학교 필수 시험 문제 ㅋㅋㅋㅋㅋ)
오버로딩 : 매개변수를 달리하여 같은 이름의 함수를 중복하여 정의하는 것
오버라이딩 : 정의된 함수를 무시하고 같은 이름의 함수를 새롭게 정의하는 것
javascript의 상속
상속 관점에서 자바스크립트의 유일한 생성자는 객체뿐이다.
각각의 객체는 [[Prototype]] 이라는 은닉(private) 속성을 가진다.
프로토타입은 자신의 프로토타입이 되는 다른 객체를 가리킨다.
이를 반복하다가 결국 null
을 프로토타입으로 가지는 오브젝트에서 끝난다.(종결자)
null
은 더이상의 프로토타입이 없다고 정의됨며 프로토타입 체인의 종점역할을 한다. -by. MDN
class checking: instanceOf
자바스크립트의 모든 오브젝트와 클래스는 Javascript의 Object 을 상속한다
오브젝트는 key와 value의 집합체 object = { key: value}
Literals and properties
const obj1 = {}; //object literal
const obj2 = new Object(); //object constructor syntax
const person = { name: "kim", age: 4 };
person.hasJob = true;
delete person.hasJob;
자바스크립트는 동적 타입 언어기 때문에 오브젝트를 선언한 후에 프로퍼티를 삭제 및 추가 할 수 있다.
Computed properties (계산된 프로퍼티)
computed properties란 오브젝트에 대괄호를 사용하여 [] 프로퍼티에 접근하는 것 의미하는 것 같다.
key should be always string
console.log(person.name); //정확하게 key를 알 때
console.log(person["name"]); //key를 모를 때, key가 runtime에서 결정될 때
person["hasJob"] = true;
console.log(person["hasJob"]); //true;
Property value shorthand , Constructor function
//오브젝트를 생성하는 함수
function makePerson(name, age) {
return {
name,
age
}
}
//constructor function
function Person(name, age) {
this.name = name;
this.age = age;
}
in operator: property existence check
console.log("name" in person); //true
for...in vs for ...of, for(key in obj)
for( key in person ) {
console.log(key); //nme, age, hasJob
}
//for(value of iterable)
const arr = [1,2,3,4];
for(v of arr){
console.log(v); //1,2,3,4
}
Cloning
const user = {name: "kim", age: 20};
const user2 = user;
user2.name = "Coder";
console.log(user); //{name: "Coder", age: 20}
//old way
const user3 = {};
for (key in user) {
user3[key] = value;
}
//Object.assign
const user4 = Object.assign({}, user);
const fruit1 = { color: "red" }
const fruit2 = { color: "blue", size: "big" }
const mixed = Object.assign({}, fruit1, fruit2);
console.log(mixed); //{color: "blue", size:"big"}
정리했는데 어디갔지.
HTTP (Hypertext Transfer Protocol)
client <--- request, response ---> server
AJAX
object -> serialize -> json
Object to JSON
let json = JSON.stringify(["apple", "banana"]);
console.log(json); //["apple", "banana"]
stringify 할 때 undefined
, 함수, Symbol은 변환될 때 생략되거나 null로 변환됨
(MDN JSON/stringify)[https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify]
json -> deserialize -> object
JSON to Object
let json = JSON.stringify({
name: "kim",
age: 10,
jump: () => console.log("jump")
});
let obj = JSON.parse(json);
console.log(obj); //{name: "kim", age: 10}
object -> json 으로 변환할 때는 함수가 포함되지 않고 데이터만 변환되기 때문에 obj에 jump 메소드가 포함되어있지 않다.