본문 바로가기

JavaScript

20210513 JavaSciprt 01 Node.js 개념, 환경설정(NVM, NPM, parcel-bundler, 유의적 버전), 데이터 타입, 연산자, 반복문, 조건문, 반복문, 변수유효범위(var, let, const), 형변환(자료형의 따른 연산)

JavaScript01

Node.js

  • Node.js : Chrome V8 JS엔진으로 빌드된 JS 런타임
  • 런타임 : 프로그래밍 언어가 동작하는 환경
    • 환경종류 : 컴퓨터 or 브라우저
  • 프론트 작업할 때 도와주는 것이 필요한데 이를 NodeJS를 통해서 가능
  • HTML, CSS, JS -> Browser에서만 동작
  • 프론트 작업할 때 도와줄 수 있는 툴을 컴퓨터 환경에서 즉, NodeJS에서 활용할 수 있음
    • 이를 browser에서 결과를 보여줄려면 HTML, CSS, JS로 변환 작업이 필요하고, 변환작업을 NodeJS(컴퓨터) 에서 가능

Node.js 환경설정

NVM (Node Version Manager)

  • window는 NVM - Windows 설치
  • 유의적 버전 : 3단계의 .을 통해 버전을 나타내는 표기법
  • Nodejs 버전을 자유롭게 옮겨 다닐수 있음 (프론트 개발에 Node 버전에 영향을 받기 때문에 다른사람과 함께 작업시 문제가 될 수 있기 때문)
  • nvm ls, nvm use 버전, nvm install 버전, nvm uninstall 버전
  • 버전은 프로젝트 마다 달라질 수 있음(일반적으로 12v 추천)

NPM (Node Package Manager)

  • 다양한 기능(패키지, 모듈)들을 관리
  • Trade-off(상충관계) : 학습난도증가, 구성 복잡 vs 관리 효율증가, 손쉬운 기능 고도화
  • npm init -y
  • 개발 의존성 패키지(-D옵션) vs 일반 의존성 패키지
    • npm install parcel-bundler -D ( -D 개발할 때만 필요한 패키지),
    • npm install lodash(일반적으로 웹브라우저에서 직접 동작시 필요한 패키지)
  • module 폴더를 삭제해도 package.json, package-lock.json만 남아있으면 언제든지 npm i 를 통해서 개발 환경의 패키지를 설치 가능함
  • package-lock.json은 설치하는 패키지의 내부적 모듈(의지하고 있는 다른 모듈들) 버전 (lock은 알아서 관리가 됨)
  • package.json은 우리가 관리하는 것이고

parcel-bundler

  • 로컬환경에서 개발용 서버를 열게 도와주고, 의존성 패키지들을 browser에서 동작하게 번들화 시킴
    • parcel html 파일명 : 개발자용 서버
    • parcel build html 파일명 : 실제 제품을 위한 번들 작업을 실행 함
  • 난독화 : 빌드된 결과(제품)가 브라우저에서 해석되는 용도로서 용량을 축솨고 읽기 어렵하는 것
  • 설치된 의존성 패키지 까지 번들화(여러 모듈 패키지을 하나로 묶어내는 작업) 시켜줌
  • parcel 패키지에 의해서 번들화 시킨 dist 폴더의 파일들을 올리면 실제로 동작함

유의적 버전 (Semantic Versioning)

  • 숫자 세개와 점으로 표현됨
  • 의미가 있는 버전
  • ^Major.Minor.Patch
  • Major : 기존 버전과 호환되지 않는 새로운 버전
  • Minor : 기존 버전과 호환되는 새로운 기능이 추가된 버전
  • Patch : 기존 버전과 호환되는 버그 및 오타 등이 수정된 버전(새로운 기능은 X)
  • ^(캐럿 기호) : Major 버전 안에서 가장 최신 버전으로 업데이트 가능(최신 버전이 있으면 update를 허용한다.)
    • npm install 패키지명@특정버전 : 특정 버전의 패키지를 설치 할 수 있음 (존재하면 덮어씀)
    • npm update 패키지명 : 해당 패키지를 업데이트 함 (^기호가 있는 경우)
  • 버전 일치가 중요하게 작용함
  • json에 명시되어 있는 의존성 패키지의 버전과 실제로 설치된 버전이 차이가 있을 수 있음
    • node module에 설치 되어있는 의존성 패키지에 들어가서 josn 파일을 확인

패키지 버전 관리가 필요 없는 경우

  • 언제라도 나중에 만들어 낼수 있는 폴더 같은 경우
    • node modules : npm i
    • package.josn의 script 명령어들
  • .gitignore 파일을 작성해서 git 을 통해 버전관리시 관리하지 말 것을 알려줌
    • 파일명/ or 폴더명/

Javascript ES

  • javascript 표준화 문법
  • 크게 ES 6버전을 기준으로 오래된 브라우저 와 새로운 브라우저에서의 추가된 기능들이 동작하는 것이 다르다.
  • 그래서 이를 호환하기 위해서 BABEL 플러그인의 도움을 받아 es5버전 이하의 버전이 이해할수 있게 변환시켜 호환성을 안정화 시킨다.
  • 프로젝트 시작시, npm init -y, npm i parcel-bundler -> 환경 구축
  • 명령이 끝났음을 ; 세미 콜론으로 구분함
  • 한줄에 여러개의 명령을 작성하면 가독성이 떨어짐 그래서 코드 컨벤션(관습)을 통해서 하나의 명령은 한줄에 올 수있게 해야함 -> 그러다 보니 ;을 안붙여도 한줄에 한명령으로 인식하여 동작함 -> 나중에 번들러 사용시 압축하는 경우 ;를 자동으로 붙여줌

데이터 타입 확인

  • typeof 을 통해서 타입 확인 가능
  • null : 의도해서 비워놓은 값
  • undefined : 의도하지 않은 비워있는 값
console.log(typeof "hello world!"); // string
console.log(typeof 123); // number
console.log(typeof true); // boolean
console.log(typeof undefined); // undefined
console.log(typeof null); // object
console.log(typeof {}); // object
console.log(typeof []); // object
  • null, {}, [] : Object 타입으로 두리뭉실하게 됨 -> type을 구분해줄 필요가 있음

모호한 type을 확인 할 수 있는 함수

  • slice 함수 사용 전까지는 Object안에 담긴 data형식으로 표시 되기 때문에, 보기 편하게 하기 위해서 slice 함수를 통해 (start , end) 부분을 잘라서 가져옴
function getType(data) {
    return Object.prototype.toString.call(data).slice(8, -1);

console.log(getType(123)); // Number
console.log(getType(false)); // Boolean
console.log(getType(null)); // Null
console.log(getType({})); // Object
console.log(getType([])); // Array

함수들을 모듈화 시켜서 관리하는 경우 (분리화)

export default function getType(data) {
  return Object.prototype.toString.call(data).slice(8, -1);
}

// 사용하고자 하는 파일에서
import getType from "./getType";
  • 단, import 문으로 가져오는 경우 from의 root가 node module로 되어 있기 때문에, npm을 통한 패키지라면 패키지 이름으로 쉽게 가져올수 있지만
  • 다른 경로에 있는 파일을 쓰려면 해당 경로를 잘 적어줘야 한다.

연산자

산술 연산자 (arithmetic operator)

// 산술 연산자

console.log(1 + 2); // 3
console.log(1 - 2); // -1
console.log(1 * 2); // 2
console.log(7 / 5); // 1.4
console.log(7 % 5); // 2

할당 연산자 (assignment operator)

// 할당 연산자 01

let a = 2;

// 할당 연산자 02

// a = a + 1;
a += 1; // 더해서 할당 : 3
console.log(a);
a -= 1; // 빼서 할당 : 2
console.log(a);
a *= 2; // 곱해서 할당 : 4
console.log(a);
a /= 2; // 나눠서 할당 : 2
console.log(a);
a %= 3; // 나머지 할당 : 2
console.log(a);

비교 연산자 (comparison operation)

const a = 1;
const b = 2;
console.log(`a = ${a}, b = ${b}`); // a = 1, b = 2

// 비교 연산자 (comparison operation)

// '===' 일치 연산자
console.log("a === b : ", a === b); // a === b :  false

// `!==` 불일치 연산자
console.log("a !== b : ", a !== b); // a !== b :  true

console.log("a > b : ", a > b); // a > b :  false
console.log("a < b : ", a < b); // a < b :  true

//주의) 이퀄기호는 꺽쇠기호보다 뒤에 작성
console.log("a >= b : ", a >= b); // a >= b :  false
console.log("a <= b : ", a <= b); // a <= b :  true

// 비교 함수
function isEqual(x, y) {
  return x === y;
}

console.log("isEqual : ", isEqual(1, 1)); // isEqual :  true
console.log("isEqual :", isEqual(1, "1")); // isEqual : false

논리 연산자 (logical operator)

const a = 1 === 1;
console.log(`a: ${a}`); // a: true

const b = "AB" === "ABC";
console.log(`b: ${b}`); // b: false

const c = true;
console.log(`c: ${c}`); // c: true

// **** 논리 연산자 (logical operator) ****

// 1) And 연산자 : 모두 true인 경우 true (하나라도 false면 false)
// 연산순서 : 내부적으로 false가 나오는 순간 연산은 끝남
console.log(`&&: `, a && b && c); // &&:  false

// 2) Or 연산자 : 하나라도 true이면 true
// 연산순서 : 내부적으로 true가 나오는 순간 연산은 끝남
console.log(`||: `, a || b || c); // ||:  true

// 3) 논리 연산자 연산 순서
function show(el) {
  console.log(`check`);
  return el;
}
console.log(`a: ${a}, b: ${b}, c: ${c}`);
// a: true, b: false, c: true
console.log(`andOrder test : `, show(a) && show(b) && show(c));
// check -> check -> andOrder : test false

console.log(`orOrder test : `, show(a) || show(b) || show(c));
// check -> orOrder test :  true

// 4) 부정 연산자, Not 연산자
console.log(`!a: ${!a}`); // !a: false

삼항 연산자(ternary operator)

const a = 1 < 2;

if (a) {
  console.log("true!");
} else {
  console.log(`false!`);
}
// true!

// 복잡한 조건이 아니면 한줄의 코드로 쉽게 가능
// 조건'?' 참 ':' 거짓
console.log(a ? "ternary : true!" : "ternary : false!");
// ternary : true!

조건문

조건문 if else

  • 랜덤 값 가져오기
// 무작위 정수 한자리 숫자 가져오기
export default function getRandom() {
  return Math.floor(Math.random() * 10);
}

// Math
// floor : 해당 값보다 크지않은 정수를 return
// random : 0 에서 1 의 숫자중 무작위로 return
  • if, if else, else
import random from "./getRandom";

const a = random();

if (a === 0) {
  console.log(`a is 0`);
} else if (a === 3) {
  console.log(`a is 3`);
} else if (a === 4) {
  console.log(`a is 4`);
} else {
  console.log(`rest...`);
}

조건문 switch

  • 어떤 값이 딱 맞게 떨어지는 경우에는 switch가 좋다.
  • 가독성이 좋지만 코드가 수직으로 길어질수 있음
  • case , braek를 통해서 시작과 끝맺음을 지어주어야 함
import random from "./getRandom";

const a = random();

switch (a) {
  case 0:
    console.log(`a is 0`);
    break;
  case 2:
    console.log(`a is 2`);
    break;
  case 4:
    console.log(`a is 4`);
    break;
  default:
    console.log(`rest...`);
}

반복문

  • for 반복문
    • for (시작조건; 종료조건(false가 되면 종료); 변화조건) {}
const ulEl = document.querySelector("ul");

console.log(ulEl);

for (let i = 0; i < 20; i += 1) {
  const li = document.createElement("li");
  li.textContent = `list-${i + 1}`;
  if ((i + 1) % 2 === 0) {
    li.addEventListener("click", function () {
      console.log(li.textContent);
    });
    li.style = "cursor: pointer";
  }
  ulEl.appendChild(li);
}

변수 유효범위

  • 변수 종류 : var, let, const
  • let, const 변수가 유효한 범위 : 선언된 블럭 내에서
    • 블록 레벨 : 변수가 선언된 중괄호 범위
  • var 변수가 유효한 범위 : 함수 범위 내에서
    • 함수 레벨 : 변수가 선언된 함수 범위 -> 사용 권장 X
    • 의도하지 않은 범위에서 변수가 사용되고 메모리가 사용됨 -> 메모리 누수 발생 가능성
  • 범위를 넘어가면 Reference Error 발생
  • 단, 모든 변수는 값이 지정되고 나서 사용이 되어야함.
  • 그렇지 않으면 undefined가 표시됨
function letConstScope() {
  // console.log(` 블록 외 let선언 전: `, a); // Reference Error
  if (true) {
    console.log(` 블록 내 let선언 전: `, a); //  블록 내 let선언 전: undefined
    let a = 123;
    console.log(` 블록 내 let선언 후: `, a); //  블록 내 let선언 후: 123
  }
  // console.log(` 블록 외 let선언 후: `, a); // Reference Error
}

letConstScope();

function varScope() {
  console.log(` 블록 외 var선언 전: `, a); // 블록 외 var선언 전: undefined
  if (true) {
    console.log(` 블록 내 var선언 전: `, a); //  블록 내 var선언 전: undefined
    var a = 123;
    console.log(` 블록 내 var선언 후: `, a); //  블록 내 var선언 후: 123
  }
  console.log(` 블록 외 var선언 후: `, a); //  블록 외 var선언 후: 123
}

varScope();

형 변환 (Type conversion)

  • javascript 만의 특징으로 자료의 형태를 알아서 인지하여 연산하는 현상을 말함
  • 동등 연산자 : 일치 연산자와 다르게 좀더 유연하게 자료형을 비교하는 연산자
  • Truthy, Falsy는 if에서만 작용하는 매커니즘이지 완전히 일치하지는 않음
    • Truthy(참 같은 값)
      • true, {}, [], 1, 2, 'false', -12, '3.14' ...
    • Falsy (거짓 같은 값)
      • false, '', null, undefined, 0, -0, NaN
if ("false") {
  console.log(123);
}

const a = 1;
const b = "1";
const c = 3;

function operator(exp) {
  return ` (${typeof exp}) : ${exp}`;
}
  • '==' 동등연산자 (되도록 안쓰는게 좋음 -> 일치연산자 사용 권장)
console.log(`1 == '1'`, operator(a == b)); // 1 == '1'  (boolean) : true
console.log(`1 == true `, operator(1 == true)); // 1 == true   (boolean) : true
console.log(`0 == false`, operator(0 == false)); // 0 == false  (boolean) : true
console.log(`0 == ''`, operator(0 == "")); // 0 == ''  (boolean) : true
  • Truthy, Falsy는 if에서만 작용하는 매커니즘이지 완전히 일치하지는 않음
console.log(`0 == null`, operator(0 == null)); // 0 == null  (boolean) : false
console.log(`false == null`, operator(false == null)); // false == null  (boolean) : false
console.log(`0 == undefined`, operator(0 == undefined)); // 0 == undefined  (boolean) : false
console.log(`false == undefined`, operator(false == undefined)); // false == undefined  (boolean) : false
console.log(`1 == {}`, operator(1 == {})); // 1 == {}  (boolean) : false
console.log(`true == {}`, operator(true == {})); // true == {}  (boolean) : false
console.log(`1 == []`, operator(1 == [])); // 1 == []  (boolean) : false
console.log(`true == []`, operator(1 == [])); // true == []  (boolean) : false

다른 자료형과의 '+'연산

  • string + number (숫자와 문자를 합산하는 순간 그 다음 부터의 모든 number는 문자로서 결합 )
console.log(`1 + '1'`, operator(a + b)); // 1 == '1' (string) : 11 -> n + s
console.log(`1 + '1' + 3`, operator(a + b + c)); // 1 + '1' + 3 (string) : 113 -> n + s + n
console.log(`1 + 3 + '1'`, operator(a + c + b)); // 1 + 3 + '1' (string) : 41 -> n + n + s
console.log(`'1' + 1 + 3`, operator(b + a + c)); // '1' + 1 + 3 (string) : 113 -> s + n + n
  • number + boolean (boolean이 숫자로 해석됨)
console.log("1 + true", operator(1 + true)); // 1 + true  (number) : 2
console.log("1 + false", operator(1 + false)); // 1 + false  (number) : 1
  • number + null , undefined, NaN
console.log("1 + null", operator(1 + null)); // 1 + null  (number) : 1
console.log("1 + undefined", operator(1 + undefined)); // 1 + undefined  (number) : NaN
console.log("1 + NaN", operator(1 + NaN)); // 1 + NaN  (number) : NaN
  • number + 그 외
console.log(`1 + ''`, operator(1 + "")); // 1 + ''  (string) : 1
console.log("1 + {}", operator(1 + {})); // 1 + {}  (string) : 1[object Object]
console.log("1 + []", operator(1 + [])); // 1 + []  (string) : 1
console.log(`1 + ['k']`, operator(1 + ["k"])); // 1 + ['k']  (string) : 1k
  • string + boolean
console.log("`1` + true", operator(`1` + true)); // `1` + true  (string) : 1true
console.log(`'1' + false`, operator("1" + false)); // '1' + false  (string) : 1false

다른 자료 형과의 '*' 연산

  • 곱셈에서 boolea 숫자로 연산
  • 숫자와 문자는 연산이 불가하여 NaN
  • 숫자 모양의 문자형과 number와의 연산에서 number는 number로 인식
console.log(`2 * '1'`, operator(2 * b)); // 2 * '1'  (number) : 2
console.log(`2 * '안녕'`, operator(2 * "안녕")); // 2 * '안녕'  (number) : NaN
console.log(`2 * true`, operator(2 * true)); // 2 * true  (number) : 2
console.log(`2 * false`, operator(2 * false)); // 2 * false  (number) : 0

// NaN (Not a number) : number에 포함되지만 정석적인 number형은 아닌 것
// 1 + undefined
  • 형변환에 대해서 인지하고 있으면 형 변환으로 인한 원하지 않는 결과를 방지 할 수있음
  • Falsy 정도만 외워 주면 좋음