Javascript 기본문법

유하아민·2021년 8월 25일
0

javascript 적용방법

script태그를 head태그안에 넣을 경우
script태그를 body태그 가장 끝부분에 넣을 경우
head태그안에 async 속성을 사용
head태그안에 defer 속성을 사용

script태크를 head태그안에 넣을 경우

인터넷 브라우저에서 html파일을 보여줄때 위에서 아래로 순차적으로 해석해서 보여주는데 해석하는 중 script태그가 보이면 그 안에 있는 javascript 파일을 서버에서 다운받아 실행 한 후 남은 부분을 마저 로드한다. script태크를 head태그안에 그냥 포함시킬 때 문제점은 js파일을 서버에서 다운 받는 동안 뒤에 있는 html파일의 로드가 멈춰있다는 거다 이렇게 될 경우 만약 js파일이 굉장히 크다면 js파일을 다운로드 하는동안 페이지를 볼 수 없기 떄문에 사용자에게 페이지를 보여주는 시간이 길어질 것이다.

script태그를 body태그 가장 끝부분에 넣을 경우

script태그를 body태그 끝에 넣는다면 브라우저가 js파일을 가장 늦게 해석하기 때문에 사용자에게 html과 css로 구성된 페이지는 빨리 보여줄 수 았지만 만약 만든 웹사이트가 j.s파일에 굉장히 의존적이라면 사용자가 정상적인 페이지를 보기위해 js파일을 다운로드하는 시간과 실행하는 시간도 기다려야하는 단점이 있다.

head태그안에 async 속성을 사용

async속성을 위에 방법들과는 달리 병렬방식으로 script태그 안에 있는 js파일을 다운 받으라는 명령만 내려놓고 동시에 나머지 html파일을 계속 해석하다가 js파일이 다운로드 되면 html파일의 해석을 멈추고 js파일을 실행시킨 후 다시 해석한다. 이 방법의 경우 벙렬로 진행하기 때문에 위에 방법들보다는 다운로드 받는 시간을 절약할 수는 있지만 js파일이 html의 로드가 되기전에 다운받아져 실행이 되고 만약 js파일이 아직 로드되지 않은 html과 연관이 있다면 문제가 발생할 수 있다 또한 js파일을 실행하는 동안은 html의 로드를 멈출 수 있기 때문에 사용자가 페이지를 볼때 여전히 시간이 조금 걸릴 수 있다는 단점이 있다.

head태그안에 defer 속성을 사용

defer속성을 사용하면 async속성과 마찬가지로 병렬로 js파일의 다운로드 명령만 내리고 나머지 html코드들을 해석하는데 async속성과의 차이점은 js파일이 다운로드되면 바로 실행하는 async속성과 달리 defer속성은 js파일이 다운로드 되어도 html파일의 로드를 멈추지 않고 다 해석한 후 다운로드한 js파일을 실행한다.

async속성과 defer속성의 차이

적용해야할 js파일이 여러개인경우 async속성의 경우 코드 순서와 상관없이 먼저 다운로드 된 js파일부터 순차적으로 실행하게 되는데 만든 js파일이 순서의 의존적이라면 async속성을 사용하게 될 경우 문제가 생길 수 있다. 반대로 defer 속성의 경우 페이지가 전부 로드 될 동안 js파일을 실행하지 않고 다운로드만 받아놓았다가 페이지가 로드된 후 코드 순서에 맞게 실행시킨다. 이렇기 여러 이유를 봤을 때 head태그안에 defer속성을 사용해 js파일을 적용하는게 안전하고 좋은 방법이라 할 수 있다.

Javascript 작성방법

  • use strict
  • variable(변수)
  • operator(연산자)
  • function(함수)
  • class(클래스)
  • object(객체)
  • array(배열)
  • JSON

use strict

javascript문서를 작성할때 맨 위에 use strict을 선언하고 작성하는 것이 좋다 그 이유는 j.s언어는 굉장히 유연하게 적용되는 언어로 만들어졌는데 이 부분이 좋은 점도 있지만 코드를 만들 때 자신이 실수한 부분을 모르고 지나가는 경우가 생기기 때문에 매우 위험한 일이 생길 수 있다. use strict은 ecmascript5에 추가되어 나왔는데 use strict를 선언하면 그런 유연한 부분들을 사용할 수 없게 된다.

a = 6;
// use strict을 선언하지 않으면 위에 a라는 변수를 할당하지 않았음에도
불구하고 문제없이 정상적으로 작동한다.
let a
a = 6;
// use strict을 선언하면 이런식으로 let을 사용하여 a가 변수라는 것을
지정해줘야 문제가 생기지 않는다.

variable(변수)

변할 수 있는 값이란 뜻으로 변수로 설정된 값들은 그 내용들 바꿔줄 수 있다.

let name = 'hamin'
console.log(name);
name = 'hello';
console.log(name);

이런식으로 변수로 선언된 값든은 그 내용을 바꾸는 것이 가능하다.

block scope, global scope

block scrope는 중괄호 안에 선언하는 것으로 설정한 값이 중괄호 안에서만 적용이 되고 global scope는 중괄호 밖에 선언하는 방식으로 밖에다 선언을 하면 중괄호 안이든 밖이든 전부 적용이 된다. globalscope로 선언한 변수들은 어플리케이션이 실행되는 순간부터 메모리를 사용하기 때문에 가능한 적게 사용하는 것이 좋다.

let globalname = 'global name'
{
	let name = 'hamin'
	console.log(name);
	name = 'hello';
	console.log(name); 
    console.log(globalname); // globalname은 밖에다가 선언한 변수이기 때문에 block(중괄호)안에서도 적용된다.
}
console.log(name) // name이란 변수는 block안에 적용된 변수이기 때문에 block 밖에서는 적용이 안된다.

let과 var

let은 변수를 선언할 때 쓰는 키워드로 예전에는 var라는 키워드로 사용되다가 여러 문제점이 있어 ecmascript6부터 let이라는 키워드로 대체되었다.
var는 어디에 선언하든 항상 제일위로 선언을 끌어올려주는 hoisting현상과block scope를 무시하는 단점이 있는데 block scope를 무시한다는 건 중괄호안에 var를 선언해도 global scope처럼 밖에서도 해석이 가능하다는 거다 예전에는 이런 유연함을 이용해서 금방금방 프로그램을 만들었지만 규모있는 프로젝트를 하게됐을 경우 선언하지 않은 값들이 할당되는 등 여러문제가 발생해 이러한 문제점들을 보안한 let을 사용하는 것이 좋다.

constat(상수)

상수는 바꿔줄 수 없는 값을 의미한다. 그래서 값을 할당하고 선언한 뒤에는 절대 바꿀 수 없다. 변수값을 하는 것보다 상수값을 할당하면 좋은 점은 보안상의 이유인데 변수값과는 달리 상수값은 변하지 않기 때문에 해커들이 코드를 바꾸려해도 바꿀 수 없기 때문이다. 그렇기 때문에 값을 바꿔야할 이유가 없다면 상수값을 쓰는게 좋다. 상수를 선언한 때 쓰는 키워드는 const이다.

variable types

  • primitive type : 가장 작은 단위에 타입들로 number, string, boolean, null, undefiedn, sumbol이 있다.
  • object : primitive type을 묶어서 한 박스로 관리할 수 있게 해주는 것

primitive type

  • number : 자바스크립트에서는 다른 언어와 달리 숫자면 정수든 소숫점이든 타입은 number하나로 통일된다. 더군다나 굳이 number라는 데이터타입을 적어주지 않아도 된다.
const infinity = 1/0; 
const negativeinfinity = -1/0;
const nAn = 'not a number' / 2;
console.log(infinity);
console.log(negativeinfinity);
console.log(nAn);

특별한 숫자값으로 infinity, negativeinfinity, nAn이 있는데 위에 예시처럼 플러스값을 0으로 나누면 무한대 값이 나오기 때문에 infinity라는 값이 나오고 마이너스값을 0으로 나누면 그 반대인 negativeinfinity값이 나온다. nAn는 숫자가 아닌 것을 나누었을 때 나오는 값이다. 이런 부분을 확인하지 않고 만들었을 경우 사용자에게 이런 특별한 숫자값이 주어질 수 있으니 조심해야 한다.

  • string: 자바스크립트에 있는 모든 문자열을 의미한다.문자열을 작성할 때는 '',"" 사이에 넣어 문자열임을 표기해주어야 한다.
const char = 'c';
const brendan = 'brendan';
const greeting = 'hello' + brendan;
console.log(`value: ${greeting}, type: ${typeof greeting}`);
const helloBob = `hi ${brendan}`;
console.log(`value: ${helloBob}, type: ${typeof helloBob}`);

`(백틱)기호와 ${}기호를 사용하는 문법은 template literals이라는 방식으로 문자열과 변수를 적을 때 매번 ''와 +기호를 사용해야하는 번거로움을 줄여줄 수 있다.

  • Boolean: 참 과 거짓 두가지 값만을 가질 수 있는 데이터타입이다.
    false값으로는 0, null, undefined, NaN, ''이 있고 이 외 값들은 true값이다.
const canRead = true;
const test = 3 < 1;
console.log(`value: ${canRead}, type: ${typeof canRead}`);
console.log(`value: ${test}, type: ${typeof test}`);

위에 예시처럼 바로 true나 false값을 지정해도 되고 거짓과 참을 어떤 조건에 따라 만들어 주어도 된다

  • null: 값이 없다라는 뜻의 값
  • undefined : 값을 찾을 수 없다라는 의미에 값
null과 undefined의 차이점은 null은 명학하게 아무것도 없는 상태라는 값을 할당해주는 것을 말하고 undefined는 선언은 되었는데 값이 지정되어있지 않은 경우를 말한다.
  • symbol : 고유한 식별자가 필요하거나 동시에 다발적으로 일어날 수 있는 코드에서 우선순위를 주고 싶을 때 사용한다.
const symbol1 = Symbol('id');
const symbol2 = Symbol('id');
console.log(symbol1);
console.log(symbol1 === symbol2); // 같은 문자열로 만들어도 다른 심볼로 만들어진다.

object(객체)

객체는 primitive type들을 묶어서 하나로 사용할 수 있게 해준다.

const ellie =  {name: 'ellie', age: 20};
ellie.age = 21;
console.log(ellie)

위에 예시처럼 const로 지정한 값은 상수이기 때문에 바뀔 수 없다. 하지만 객체를 상수로 지정하면 그 안에 값들을 바로 상수로 지정한 것이 아닌 그 밖에 reference를 상수값으로 지정한 것이기 때문에 그 안에 아이템들은 변경이 가능하다.

dynamic typing

타입을 따로 지정하지 않고 프로그램이 동작할 때 할당된 값에 따라 변경될 수 있다는 것을 의미하는데

let text = 'hello'
console.log(text.charAt(0));
console.log(`value: ${text}, type: ${typeof text}`);
text = 1;
console.log(`value: ${text}, type: ${typeof text}`);
text = '7' + 5
console.log(`value: ${text} type: ${typeof text}`);
text = '8' / '2';
console.log(`value: ${text} type: ${typeof text}`);

이런식으로 문자열과 숫자열을 구분하지 않았음에도 자바스크립트엔진이 유연하게 해석해서 결과를 도출한다.

operator(연산자)

  • string concatenation :

    +기호로 문자열과 문자열을 합칠 수 있다.
console.log('my' + 'cat');
console.log('1' + 2);
console.log(`string literals: 1 + 2 = ${1 + 2} `);
  • Numeric operators

    숫자 연산자
console.log(1 + 1); // 더하기
console.log(1 - 1); // 뺴기
console.log(1 / 1); // 나누기
console.log(1 * 1); // 곱하기
console.log(5 % 2); // 나눈 나머지 값
console.log(2 ** 3); // 2의 3승
  • Increment and decrement operators

    증가 감소 연산자
let counter = 2;
const preIncrement = ++counter; 
// counter = counter + 1;
// preIncrement = counter; 
console.log(`preIncrement: ${preIncrement}, counter: ${counter}`);
const postIncrement = counter++;
console.log(`preIncrement: ${postIncrement}, counter: ${counter}`);
// postIncrement = counter;
// counter = counter + 1; 
const preDecrment = --counter; // 앞에 두개의 -를 붙이는 걸 preDecrment라 부른다 preIncrement와 반대로 지정한 값의 1을 뺀 값을 할당한다.
console.log(`preIncrement: ${preDecrment}, counter: ${counter}`);
const postDecrment = counter--; // postIncrement과 반대로 뒤에 -를 붙이는 걸 postDecrment라 부른다. 1을 빼기전에 값을 할당 하고 그 후에 1을 뺀다.
console.log(`preIncrement: ${postDecrment}, counter: ${counter}`);
  1. 앞에 두개의 +를 붙이는 걸 preIncrement라 부른다 preIncrement를 사용하면 지정한 값의 1을 더한 값을 할당한다. 지정한 값 또한 1이 더해진다.
  2. 뒤에 +를 붙이는 걸 postIncrement라 하는데 postIncrement 사용하면 1을 더하기 전에 값을 할당하고 다음에 1을 더한다는 뜻이다.
  3. 앞에 두개의 -를 붙이는 걸 preDecrment라 부른다 preIncrement와 반대로 지정한 값의 1을 뺀 값을 할당한다.
  4. postIncrement과 반대로 뒤에 -를 붙이는 걸 postDecrment라 부른다. 1을 빼기전에 값을 할당 하고 그 후에 1을 뺀다.
  • Assignment operators

    할당연산자로 오른쪽 값을 왼쪽 연산자로 할당한다.
let x = 3;
let y = 6;
x += y; // x = x+y 와 같은 뜻이다.
x -= y;
x *= y;
x /= y;
  • Comparison operators

    비교연산자로 두 피연산자를 비교해 결과가 참인지 거짓인지에 따라 결과를 도출한다.
console.log(10 < 6);
console.log(10 <= 6);
console.log(10 > 6);
console.log(10 >= 6);
  • Logical operators

    논리 연산자로 세가지의 방식으로 참과 거짓을 구분한다.
const value1 = false;
const value2 = 4 < 2;
console.log(`or: ${value1 || value2 || check()}`);
console.log(`or: ${value1 && value2 && check()}`);
function check() {
    for (let i = 0; i < 10; i++) {
        console.log('😱');
    }
    return true;
}
console.log(!value1);
  1. ||(or) : or은 안에 값들중 하나라도 true가 있으면 true로 계산되는 연산자이다. 처음 값이 true면 즉시 중지 되고 바로 true로 인식하기 때문에 코드가 복잡하거나 연산이 복잡한 함수를 앞에 넣는 것보다 값이 간단한 것을 앞에 배치하는 것이 좋다.
  2. && (and) : and는 안에 있는 모든 값이 true일 때 true라고 생각한다. 처음 값이 false면 멈추고 false라고 인식한다. 그렇기 때문에 or과 마찬가지로 계산하기 어려운 것일수록 뒤에 배치하는 것이 좋다.
  3. ! (not) : 가지고 있던 값을 반대로 바꿔주는 연산자이다.
  • Equality

    비교연산자로 =를 붙이는 갯수의 따라 의미가 달라진다.
const stringFive = '5';
const numberFive = 5;
console.log(stringFive == numberFive);
console.log(stringFive != numberFive);
console.log(stringFive === numberFive);
console.log(stringFive !== numberFive);
  1. loose equality : 두개의 Equality 쓴것으로 두 값을 비교할 때 타입이 달라도 타입을 변경해서 값이 같은 지 확인한다.
  2. strict equality : 세개의 Equality를 쓴것으로 타입까지 신경써서 같은 지 확인한다. 웬만하면 strict equality로 검사하는 게 좋다.
  • Conditional operators

    삼항 조건 연산자로 if문을 사용하는데 처음 if 괄호안에 값이 참이라면 if 중괄호안에 있는 것이 실행되고 거짓이라면 else if로 넘어가 그 값이 참이라면 그 안에 것을 실행하고 거짓이면 마지막 else의 값을 실행한다.
 const name = 'ellie'
if(name === 'ellie') {
    console.log('welcome, ellie!');
} else if(name === 'coder') { 
    console.log('your are amazing coder');
} else {
    console.log('unkwnon');
}
  1. ernary operator
    if문을 조금더 간단하게 사용할 수 있는 연산자로 if 괄호 안에 값 다음에 ?표를 붙여 그것이 참이라면 : 왼쪽에 있는 걸 실행하고 거짓이라면 : 오른쪽에 있는 걸 실행한다. 이것을 계속 묶어서 길게 사용하면 코드의 가독성이 떨어져 좋지 않다.
console.log(name === 'ellie' ? 'welcome, ellie!' : 'your are amazing coder');
  1. Switch statement
    if문과 비슷한데 switch 괄호안에 값과 case의 값이 같은 것을 실행한다. if문에서 else, if를 많이 반복해야 한다면 switch를 사용하는 것이 좋다.
    chrome과 Firefox의 값은 같은 것을 도출허기 때문에 묶을 수 있다.
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을 사용하는데 while은 괄호안에 값이 false가 될 때까지 반복한다.

  1. while
let i = 3;
while (i > 0) {
    console.log(`while: ${i}`);
    i--;
}
  1. do while loop : while안에 값이 참인지 거짓인지 판단하지 전에 do 안에 있는 것을 먼저 실행하고 그 밑에 while이 거짓이면 멈춘다.
let i =3;
do {
    console.log(`do while: ${i}`);
    i--;
} while (i < 0);
  1. for loop : for는 begin, condition, step 이렇게 나눠지는데 먼저 begin을 처음에 한번 호출을 하고 그 다음 블록을 실행하기 전 condition 맞는지 안맞는지 확한 후 블록이 실행이 되면 마지막 step을 실행한다. 이렇게 condition이 안맞을 때까지 무한히 실행하게 된다.
    두번째 예시처럼 for문 안에 변수를 직접 설정해주어도 괜찮다.
for (i = 3; i > 0; i--) {
    console.log(`for: ${i}`);
}
for (let i = 3; i > 0; i = i -2) { 
    console.log(`inline variable for: ${i}`);
}
  1. nested loops : for문 안에 다시 for문을 사용하는 방식인데 이런식으로 작성하면 cpu에 좋지 않아 사용하지 않는 것이 좋다.
for (let i = 0; i < 10; i++) {
    for(let j = 0; j < 10; j++) {
        console.log(`i: ${i}, j: ${j}`);
    }
}

function(함수)

  • 프로그램을 구성하는 가장 작은 단위
  • 서브프로그램이라고도 불리고 여러번 재사용 할 수 있다.
  • 한가지의 작업이나 어떠한 계산을 할 때 사용

1. 함수 선언

  • 함수의 기본 구조 : function name(param1, param2) { body... return; }
  • 한개의 함수는 한가지의 일만 하도록 만들어야한다.
  • 함수의 이름을 작성할때는 동사형태로 이름을 지정해줘야한다.
  • 자바스크립트에서 함수는 object(객체)다.
function printHello(){
    console.log('hello');
}
printHello();
function log(message) {
    console.log(message);
}
log('hello');

2. parameters(매개변수)

  • primitive parameters : value값을 바로 전달
  • object parameters : 객체의 reference 값을 전달
function changName(obj){
    obj.name = 'coder';
}
const ellie = {name: 'ellie'};
changName(ellie);
console.log(ellie);

3. Default parameters

기본매개변수 변수값을 지정하지 않았을 때 기본적으로 나올 값을 지정해준다.
hi 다음에 나올 변수를 지정하지 않으면 undefined라고 나오는데 그 말을 지정할 수 있다.

function showMessage(message, from = 'unknown'){
    console.log(`${message} by ${from}`);
}
showMessage('hi');

4. Rest parameters

이름을 지정하지 않은 배열을 말한다. 앞에 닷(.) 세개를 붙여 지정해주면 값이 배열로 할당된다.

function printall(...args){
    for (let i =0; i < args.length; i++) {
        console.log(args[i]);
    }
}
printall('dream', 'coding', 'ellie');

5. Local scope

블록 내부에 선언된 경우를 말한다. 블록 내부에 선언된 변수들은 그 안에서만 작용한다.
블록 밖에 선언된 globalMessage는 안에서 출력이 되지만 블록 안에서 선언된 변수는 밖에서 사용할 수 없다.

let globalMessage = 'global'; 
function printMessage() {
    let message = 'hello'
    console.log(message);
    console.log(globalMessage);
}
printMessage();

6. Return a value

함수 실행을 종료하고 그 값을 내보낸다. 모든 함수에는 return 이나 return undefined(생략가능)이 있다.

function sum(a, b) {
    return a + b;
}
const result = sum(1,2);
console.log(`sum: ${sum(1,2)}`);
console.log(sum(4,5));

First-class Function

  • 함수를 변수나 자료구조에 저장할 수 있다.
  • 함수의 매개변수(인자)에 다른 함수를 인수로 전달할 수 있다.
  • 함수의 반환 값(return 값)으로 함수를 전달할 수 있다.

Callback function(콜백 함수)

  • 콜백함수는 함수에 매개변수로 들어가는 함수를 뜻한다. 아래 예시처럼 총 세개의 함수가 있는데 printYes와 printNo라는 함수는 randomQuiz라는 함수의 매개변수로 들어가 있는데 이때 printYes와 printNo를 콜백함수라 한다.
function sum(a, b) {
    return a + b;
}
const print = function() {
    console.log('print');    
};
print();
const printAgain = print;
printAgain();
const sumAgain = sum;
console.log(sumAgain(1, 3));

Arrow function

=> 표시를 사용해 함수를 간단하게 만들 수 있다. 단 함수 이름을 지정하지 못한다.

const simplePrint = () => console.log('simplePrint');
const add = (a, b) => a + b;

IIEF

작성한 함수를 간단하게 바로 확인할 수 있는 방법

(function hello() {
    console.log('IIEF');
})();

class(클래스)

클래스는 객체 지향 프로그래밍에서 특정 객체를 생성하기 위해 변수와 메소드를 정의하는 일종의 틀이다. 정의한 클래스에 데이터를 넣어주면 객체가 된다.

1. clss declarations

클래스를 정의하는 한 가지 방법은 클래스 선언을 사용하는 것이다. 클래스를 선언하려면 클래스 이름과 함께 class 키워드를 사용해야한다.

class Person {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
    speak() {
        console.log(`${this.name}: hello!`);
    }
} 
const ellie = new Person('ellie', 20);
console.log(ellie.name);
console.log(ellie.age);
ellie.speak();

2. getter and setters

getter setters는 클래스 사용자가 정보를 잘못 적었을 경우 그거에 대비해주는 역할을 한다. 예를 들어 아래 예시를 보면 사람의 나이가 마이너스가 될 수 없기 때문에 getter와 setters를 설정해서 나이를 기입하면 바로 출력되는 것이 아닌 getter에서 바로 리턴이 되고 setters에서 설정 해놓은 값으로 출력이 된다. 이렇게 하면 사용자가 실수할 것을 대비해 좀 더 나은 환경을 제공할 수 있다.

class User { 
    constructor(firstName, lastName, age) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.age = age; 
    }   
    get age() { 
        return this._age;
    }
    set age(value) {
        // if (value < 0) {
        //     throw Error('are can not be negative');
        // }
        this._age = value < 0 ? 0 : value;
    }
}

3. Fields (public $ Private)

constructor를 쓰지 않고 Fields를 정의 할 수 있는데 publicFields로 만들면 값이 외부에서도 보여지고 변경이 되는데 PrivateFields로 만들면 값이 외부에서 보여지지 않고 변경도 할 수 없다.PrivateFields를 사용하려면 앞에 #을 붙이면 된다.

class Experiment {
    publicFields = 2;
    #privateFields = 0;
}
const experiment = new Experiment();
console.log(experiment.publicFields);
console.log(experiment.privateFields);

4. Siatic

클래스가 가지고 있는 고유의 값을 설정해줄 때 사용한다. 이 함수를 사용하지 않고 값을 설정하면 이 클래스로 만든 오브잭트들은 그 클래스가 가지고 있는 값들을 가지게 되는데 Siatic을 사용하면 클래스 자체에만 값을 설정해준다. 아래 예시처럼 새로 만든 article1,article2 에서는 publisher를 찾을 수 없다.

class Article {
    static publisher = 'Dream coding'
    constructor(articleNumber) {
        this.articleNumber = articleNumber;
    }
    static printPublisher(){
        console.log(Article.publisher);
    }
}
const article1 = new Article(1);
const article2 = new Article(2);
console.log(article1.publisher);
console.log(Article.publisher);
Article.printPublisher();

5. inheritance

상속 비슷하게 써야하는 다른 클래스가 있다면 하나의 클라스를 만들어 놓고 extends라는 속성을 통해 그 클래스를 상속 시킬 수 있다.
상속의 장점은 비슷한 비슷한 클래스를 만들 때 하나하나 전부 새롭게 만드는 게 아니라 필요한 부분을 바로 상속받아 사용하고 수정해야 하는 부분만 수정할 수 있기 때문에 코드가 길어지지 않고 번거로움이 사라진다.
아래 예시처럼 Shape이라는 큰 틀의 클래스를 만들고 그 밑에 Rectangle, Triangle 라는 다른 클래스를 만들 때는 Shape의 속성과 메소드 값들을 그대로 상속하고 수정할 부분들만 따로 수정을 해서 사용할 수 있다. 대신 수정을 하면 상속받은 클래스가 가지고 있는 값들은 없어지는데 수정한 것과 상속받은 값도 같이 사용하려면 super라는 키워드를 붙여 가져오면 된다.

class Shape {
    constructor(width, height, color) {
        this.width = width;
        this.height = height;
        this.color = color;
    }
    draw() {
        console.log(`drawing ${this.color} color!`);
    }
    getArea() {
        return this.width * this.height;
    }
}
class Rectangle extends Shape {}
class Triangle extends Shape {
    draw() {
        super.draw() 
        console.log(`🔺`);
    }
    getArea() {
        return this.width * this.height / 2;
    }
}
const rectangle = new Rectangle(20, 20, 'blue');
rectangle.draw();
console.log(rectangle.getArea());
const triangle = new Triangle(20, 20, 'red');
triangle.draw();
console.log(triangle.getArea());

6. Class checking

instanceOf 키워드는 클래스를 확인시켜줄 때 사용하는 키워드인데 A라는 클래스로 만든 a라는 객체에 적용을 하면 true값이 나오고 다르면 false값이 출력된다.

console.log(rectangle instanceof Rectangle); // t
console.log(triangle instanceof Rectangle); // f
console.log(triangle instanceof Triangle); // t
console.log(triangle instanceof Shape); // t 
console.log(triangle instanceof Object); // t

object(객체)

어떤 속성과 값들을 설정 할 때 설정한 변수 값들이 많아지면 그것들을 전부 하나씩 따로 설정을 하면 관리하기가 불편하고 코드가 길어질텐데 이를 한대 묶어 하나의 변수로 그룹화 한것을 객체라고 한다.

1. Literals and properties

객채를 선언하는 방법은 2가지가 있는데 하나는 클래스를 사용해 만드는 방법이고 하나는 중괄호를 사용하는 거다. 괄호를 사용해 만드는 것을 Literals 이라고 한다.
밑에 예시처럼 자바스크립트는 중간에 원하는 변수값을 객체 인자값으로 넣을 수가 있는데 중간에 넣게 되면 알아보기도 힘들고 관리하기 불편하기 때문에 안하는 것이 좋다.

function print(person) {
    console.log(person.name);
    console.log(person.age);
}
const ellie = {name: 'ellie', age: 20};
print(ellie);
ellie.hasjob = true;
console.log(ellie.hasjob);
delete ellie.hasjob;
console.log(ellie.hasjob);

2. computed properties

객체의 속성을 가져올 때 .을 쓰는 경우가 있고 []를 이용해 가져올 수 있는데 []를 써서 가져오는 방법을 computed properties 이라고 한다./
computed properties를 사용할 때는 key값이 정확하지 않을 때나 실시간으로 key값을 받아와야 할 때 사용한다.

console.log(ellie.name);
console.log(ellie['name']);
ellie['hasjob'] = true;
console.log(ellie.hasjob);
function printValue(obj, key) {
    console.log(obj[key]);
}
printValue(ellie, 'name');
printValue(ellie, 'age');

3. Property vlaue shorthand

key와 value의 이름이 동일하다면 생략해도 되는데 그걸 Property vlaue shorthand라 한다.

const person1 ={name: 'bob', age: '2'};
const person2 ={name: 'steve', age: '3'};
const person3 ={name: 'dave', age: '4'};
const person4 = new Person('ellie', 5);
console.log(person4);
function Person(name, age) {
  return {
    name,
    age,
  };

4. Constructor Fuction

클래스가 없었을 때는 클래스의 역할을 함수가 대신 했는데 클래스 대신 사용하던 함수를 Constructor Fuction라 한다.

function Person(name, age) {
    this.name = name;
    this.age = age;
}

5. in operator

해당 객체 안에 해당하는 key가 있는 지 확인할 해서 있으면 true 없으면 false값을 출력한다.

console.log('name' in ellie);
console.log('age' in ellie);
console.log("rnadom" in ellie);
console.log(ellie.random);

6. for..in vs for..of

for 는 반복문을 할 때 사용했는데 in을 사용하면 객체에 사용하면 객체 안에 있는 모든 키들을 전부 할당해서 보여주고 of을 사용하면 배열안에 있는 모든 값들을 할당한다.

for (key in ellie) {
    console.log(key);
}
const array = [1, 2, 3, 4];
for (value of array) {
    console.log(value);

7. cloning

복제를 하는 방법은 밑에 예시처럼 = 로 가은 값을 할당해주면 되는데 저렇게 하면 객체안에 값은 같아도 객체가 가지고 있는 reference는 다르다. reference까지 같게 하려면 for in을 사용해 밑에처럼 키들을 다 같게 만들거나 Object.assign을 사용해서 합쳐주면 된다. assign은 안에 있는 값들을 합쳐주는 역할을 한다.
assign은 같은 키값이 들어있는 객체를 합치면 뒤에 있는 객체의 키값으로 앞에 있는 객체의 키값이 덮어써지기 때문에 사용할 때 주의해야 한다.

const user = { name: 'ellie', age: '20'};
const user2 = user;
user2.name = 'coder'
console.log(user2.name);
const user3 = {};
for (key in user) {
    user3[key] = user[key];
}
console.log(user3);
const user4 = {}
Object.assign(user4, user);
console.log(user4);
const user5 = Object.assign({}, user);
console.log(user5);

array(배열)

비슷한 타입의 객체들이나 변수값들을 묶어두는 걸 배열이라 한다. 다른 언어에서는 동일한 타입의 데이터들만 묶을 수 있지만 자바스트립트에서는 다양한 종류의 타입들을 다 묶어둘 수 있지만 좋은 방법은 아니다.

1. Declaration

배열의 선언방법은 객체를 만들때와 같이 new라는 키워드를 이용해 만들 수 도 있고 []를 이용하는 방법이 있다.

const arr1 = new Array();
const arr2 = [1, 2];

2. index position

배열은 index를 기준으로 저장이 된다. 배열의 값들에 접근하려면 값이 저장되있는 index의 번호를 이용해 값들을 지정할 수 있다. index는 처음이 0으로 시작하기 때문에 첫번째 사과를 출력하기 위해서는 0을 입력해야 한다.

const fruits = ['🍎', '🍌'];
console.log(fruits);
console.log(fruits[0]);
console.log(fruits[1]);
console.log(fruits[2]);
console.log(fruits[fruits.length - 1]);

3. Looping over an array

배열의 있는 모든 값들을 선택하는 방법은 for를 사용하면 되는데 첫번째 방법은 처음 for문을 배웠을 때 사용했던 조건을 걸어주는 방법이고 두번째는 for of을 사용하면 안에 있는 값들을 전부 선택하는 방법이 있고 마지막 foreEach api를 사용하면된다.

(1). for
for<(let i = 0; i < fruits.length; i++) {
    console.log(fruits[i]);
}
(2). for of
for(let fruit of fruits) {
    console.log(fruit);
}
(3). foreEach
 fruits.forEach(function (fruit, index) {
     console.log(fruit, index);
});
fruits.forEach((fruit) => console.log(fruit));

4. Addtion, deletion, copy

배열의 값을 더하고 빼고 복사하는 방법

  • push: 아이템을 뒤에다가 추가
fruits.push('🍓', '🍑');
console.log(fruits);
  • pop: 뒤에 있는 아이템을 제거
fruits.pop();
const poped = fruits.pop();
console.log(poped);
console.log(fruits);
fruits.pop();
console.log(fruits);
  • unshift: 아이템을 앞에다가 추가
fruits.unshift('🍓','🍑')
console.log(fruits);
// shift: 앞에 위치한 아이템을 삭제
fruits.shift();
console.log(fruits);
fruits.shift();
console.log(fruits);
  • splice: 지정된 위치에 아이템을 지우기
fruits.push('🍎', '🍑', '🍋');
console.log(fruits);
fruits.splice(2,1);
console.log(fruits);
fruits.splice(2.1, '🍉', '🍇');
console.log(fruits);
  • combine two arrays : 두 배열을 합쳐주는 역할을 한다.
const fruits2 = ['🍐', '🥥']
const newFruit = fruits.concat(fruits2);
console.log(newFruit);

shift , unshift 는 pop, push 보다 느리다. 이유는 뒤에 추가하거나 제거할때는 바로 추가와 제거를 하면 되는데 앞에다 하는 경우 앞에 있던 값들을 뒤로 보내는 과정에서 시간이 발생한다. 그렇기 때문에 pop, push를 사용하는 것이 좋다.

5. Searching

배열안에 어떤 값이 몇번째 index에 있는 지 알 수 있게 해준다.
indexOf는 몇번째 index인지 알려주고 includes는 배열안에 있는 값인지 아닌지 불린 값으로 알려준다.lastIndexOf은 배열안에 값이 같은게 있다면 indexof은 처음에 나온 것을 알려주고 lastIndexOf은 뒤에 있는 값의 순서를 출력한다.

console.log(fruits);
console.log(fruits.indexOf('🍎'));
console.log(fruits.indexOf('🍌'));
console.log(fruits.indexOf('🍉'));
console.log(fruits.includes('🍉'));
console.log(fruits.includes('🍎'));

JSON

  • 서버와 데이터 통신을 할때 때 쓸수있는 가장 간단한 데이터 포맷
  • 텍스트를 기반으로하는 가볍고 사람 눈으로 읽기도 편하고 키와 벨류로 이루어져 있는 파일포맷이다
  • 데이터를 서버와 주고 받을 때 직렬화하여 전송할 때 쓰이고 프로그램 언어와 플랫폼의 상관없이 쓸 수 있다.

1. Object to JSON

  • 객체를 JSON으로 변경하는 방법은 stringify를 사용하면 된다.
  • 배열을 배열로 보내면 자바스크립트에서 쓰는 것처럼 []로 표현되지만 안에 ''가 아닌 ""로 각 값들이 들어가있다.
  • 함수랑 심볼은 JSON으로 변경이 안된다.
  • 콜백함수를 사용해 좀 더 세밀하게 통제할 수 있다.
let json =  JSON.stringify(true);
console.log(json);
json = JSON.stringify(['apple', 'banana']);
console.log(json);
const rabbit = {
    name: 'tori',
    color: 'white',
    size: null,
    birthdate: new Date(),
    // symbol: Symbol('id'),
    jump: () => {
        console.log(`${name} can jump!`);
    },
};
json = JSON.stringify(rabbit);
console.log(json);
json = JSON.stringify(rabbit, ['name','color', 'szie']);
console.log(json);
json = JSON.stringify(rabbit, (key, value) => {
    console.log(`key: ${key}, value: ${value}`);
    return key === 'name' ? 'ellie' : value;
});
console.log(json);

2. JSON to Object

  • JSON을 객체로 바꾸는 방법은 parse를 사용하면 된다.
  • 객체에서 JSON으로 바꿔줄 때 함수는 바꿔주지 못하므로 사라진다 그래서 그 것을 다시 객체로 바꿔주어도 함수가 다시 생기지 않는다.
  • parse 또한 함수를 통해 좀 더 다양한 통제가 가능하다.
json  = JSON.stringify(rabbit)
const obj = JSON.parse(json, (key, value) => {
    console.log(`key: ${key}, value: ${value}`);
    return key === 'birthdate' ? new Date(value) : value;
} );
console.log(obj);
rabbit.jump();
// obj.jump();
console.log(rabbit.birthdate.getDate());
console.log(obj.birthdate.getDate());

javasciprt를 배우고 느낀점

확실히 기존의 배웠던 언어들과 달리 이해가 안되는 부분들도 많고 공부해야 하는 양이 많은 거 같다. 상황마다 써야 하는 메소드들이 다 다르고 작동하는 매커니즘 또한 이해하기 까다롭다. 아직 처음이라 많이 써보지 않아 익숙하지 않은 것도 큰것같다. 다양한 방식으로 많이 사용해보면서 익숙해지고 조금 더 찾아보고 공부해야 할 거 같다.

0개의 댓글