15~16일차 JavaScript Essentials

변승훈·2022년 4월 18일
0

1. 데이터 타입 (typeof)

typeof : 데이터 타입을 확인하는 연산자이다.

  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

2. Operator(연산자)

1. 산술 연산자(arithmetic operator)

기호이름
+덧셈
-뺄셈
*곱셈
/나눗셈
%나머지, 나머지를 정수로 반환
**거듭제곱

2. 할당 연산자(assginment operator)

값을 할당하는 연산자이며 "="을 사용하는 연산자 이다.

let a = 2;
  console.log(a);
  a += 1;
  // a -= 1;
  // a *= 1;
  // a /= 1;
  console.log(a);

3. 비교 연산자(comparison operator)

값을 비교하는 연산자이다.

  //  === : 일치 연산자
  a = 3;
  let b = 4;
  console.log(a === b);

  function isEqual(x, y){
    return x === y
  }

  console.log(isEqual(1,1));
  console.log(isEqual(2, '2'));

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

  // <, >, <=, >= : 크기 비교 연산자 
  console.log(a > b);
  console.log(a < b);
  console.log(a >= b);
  console.log(a <= b);

4. 논리 연산자(logical operator)

OR(||), AND(&&), NOT(!) 세가지 종류의 연산자이다.
OR(||) : 둘 중 하나의 값이 true이면 true이다.
AND(&&) : 둘 다 값이 true여야 true이다. 하나라도 false이면 false이다.
NOT(!) : 값을 부정하는 의미를 가진다. !true이면 false가 되고 !false면 true가 된다.

  a = 1 === 1
  b = 'AB' === 'ABC'
  let c = false
  let d = (1 + 2) === 3

  console.log(a);
  console.log(b);
  console.log(c);
  console.log(d);
  
  // ||
  console.log('|| : ', b || c);
  console.log('|| : ', a || b || c);
  
  // &&
  console.log('&& : ', a && b && c);  
  console.log('&& : ', a && d);

  // !
  console.log('! : ', !b);
  console.log('! : ', a !== b);

5. 삼항 연산자(ternary operator)

3개의 피연산자를 취할 수 있는 유일한 연산자이며 맨 앞에 조건문 들어간다.
그 뒤로 물음표(?)와 조건이 참truthy이라면 실행할 식이 물음표 뒤로 들어가며 바로 뒤로 콜론(:)이 들어가며 조건이 거짓falsy이라면 실행할 식이 마지막에 들어간다. 보통 if 명령문의 단축 형태로 쓰인다.

  a = 1 < 2

  if (a) {
    console.log('참')
  } else {
    console.log('거짓')
  }

  console.log(a ? '참' : '거짓')

3. 조건문 (if-else, switch, for)

조건문엔 if-else, switch, for문이 있다.

1. if-else

  1. if( ) : 작성 방법은 if() 이며 ( )안에는 조건을 기입한다.
    조건이 turthy면 if문의 코드를 실행시키고 falsy면 실행시키지 않는다.

  2. else : if와 같이 사용하며 if-else 사용 시 if의 조건에 부합하지 않는 경우 else의 코드를 실행시킨다.
    조건이 복수개인 경우 else if()로 조건을 추가 해주면 된다.

/* getRandom.js */
  export default function random() {
    return Math.floor(Math.random() * 10)
  }
/* main.js */
	import random from './getRandom'
	const a = random();
  	if (a === 0 ) {
  	  console.log('a is 0')
  	} else if (a === 2) {
  	  console.log('a is 2')
 	} else if (a === 4) {
 	  console.log('a is 4')
    } else {
      console.log('rest...')
 	};

2. switch

switch문은 if-else문이 여러개인 경우 사용한다.
위의 예시를 switch의 형태로 바꿔 보겠다.

/* getRandom.js */
  export default function random() {
    return Math.floor(Math.random() * 10)
  }
/* main.js */
  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...')
    };

case 옆의 숫자는 if나 else if의 ( )안의 조건과 같다.
만약 조건을 만족하게 되면 break를 사용하여 해당 switch문을 종료시킬 수 있다.
default는 그 어느 조건에도 해당하지 않으면 해당 코드를 출력하라는 의미이다.

3. for

for(시작조건; 종료조건; 변화조건) { } 로 사용한다.
다음은 간단한 javascript 문법을 통한 예제이다.
조건에 따른 li의 생성과 짝수의 li 요소를 클릭했을 때 console.log가 해당 짝수번을 출력하는 예제이다.

	<ul></ul>
  const ulEl = document.querySelector('ul');

  for (let i = 0; i  <  10; 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);
      })
    }
    ulEl.appendChild(li);
  }

4. 변수(Variable)와 Scope

  1. 변수는 var, let, const를 사용하며 현재는 let과 const를 주로 사용한다.
    let과 const의 차이는 let은 값의 재할당이 가능하지만 const는 값의 재할당이 불가능한 고정된 변수(상수)라고 생각하면 된다.

  2. 변수 유효범위 : Variable Scope라고도 하며 scope는 식별자(변수명, 함수명, 클래스명 ...)의 유효 범위를 뜻한다.
    선언된 위치에 따라 유효 범위가 달라지며 전역에 선언된 변수는 전역 스코프, 지역에 선언된 변수는 지역 스코프를 가진다.

  • 전역 변수 : 어디에서든지 참조가 가능한 값이다.
  • 지역 변수 : 함수 몸체 내부를 말한다. 따라서 지역변수는 자신의 지역과 그 하위 지역 스코프에서 유효하다.
  • 블록 레벨 스코프 : javascript에서 모든 코드 블록(if, for, while, try/catch ...)이 지역 스코프를 만드는데 이러한 특성을 지칭하는 말이다.
  • 함수 레벨 스코프 : var 키워드로 선언된 변수는 오직 함수의 코드 블록만을 지역 스코프로 인정하는 것을 지칭한다.

다음 예제에서 console.log()에 있는 위치에서만 각 변수들이 인지되는 부분을 기록해 놓았다.

  function scope() {
    if (true) {
      let a = 123;
      const b = 123;
      var c = 123;
      console.log('in : ', a);
      console.log('in : ', b);
      console.log('in : ', c);	
    }
    console.log('out : ', c);	
  }
  scope()

5. 형 변환(Type conversion) & truthy falsy

1. 형 변환(Type conversion)

동등 연산자("===")를 사용하면 형 변환이 일어나며 값을 비교하게 된다.

  const a = 1;
  const b = '1';

  console.log(a === b);	// false

2. Truthy(참 같은 값)

true, {}, [], 1, 2, 'false', -12, '3.14' ...

3. Falsy(거짓 같은 값)

flase, '', null, undefined, 0, -0, NaN

6. 함수(Function)

1. 기명함수

이름을 선언한 함수

  function sum(x, y) {
    return x + y;
  };

2. 익명 함수

이름을 선언하지 않은 함수

  const sum = function (x,y){
    return x + y;
  }

3. return

return이 사용된 후 그 함수는 종료되며 return이후의 코드는 실행되지 않는다.

4. 함수 호출 방법

  1. 단일로 사용될 때, 그대로 함수를 호출한다.
	console.log(sum(1,2));
  1. 함수가 반복적으로 사용될 때, 변수에 담아서 사용한다.
  const a = sum(1,3);
  const b = sum(4,12);


  console.log(a);
  console.log(b);
  console.log(a+b);

5. 화살표 함수

기본적으로 사용하는 방법인 function ( ) { }을 ( ) => { }로 사용하는 방법이다.
화살표 함수는 총 일반 화살표, 축약형, 객체데이터 축약형 총 3가지 방식으로 표현할 수 있다.

아래는 화살표 함수의 3가지 방식과 기존 function( ) { }을 이용한 방식을 비교해 놓았다.

  const double = function (x) {
    return x * 2
  };

  console.log('double: ', double(7));

  // 1. 기본 화살표 함수 사용 방법
  // const doubleArrow = (x) => {
  //   return x * 2
  // }

  // 2. 축약형
  const doubleArrow = x => x * 2
  
  // 3. 객체데이터 축약형, ★소괄호를 사용해줘야함!
  // const doubleArrow = x => ({name:'Hun'})


  console.log('doubleArrow', doubleArrow(7));

6. 즉시 실행 함수(IIFE, Immediately-Invoked Function Experssion)

  1. 익명의 함수로 만들고 ()를 만들어 실행하는 방식이다.

  2. 소괄호를 안에 넣어서도 사용이 가능하며 권장하는 방식이다.

  const a = 7;
  function double() {
    console.log(a * 2)
  }

  double();

  // 1. 즉시 실행 함수, 익명의 함수로 만들어 ()를 만들어 실행
  (function() {
    console.log(a * 2);
  })();

  // 2. 소괄호를 안에 넣어서도 가능, 권장 방법

  (function() {
    console.log(a * 2);
  }());

7. 호이스팅(Hoisting)

함수 선언부가 유효범위 최상단으로 끌어 올려지는 현상이다.

  const a = 7;

  double();

  function double() {
    console.log(a * 3);
  }

위의 예시처럼 함수 선언부가 위에 있고 아래에 함수가 정의되어 있는 방식이며 앞으로 함수를 선언할 때 호이스팅을 권장한다.

8. 타이머 함수(timer function)

타이머 함수에는 4종류가 있다.

  1. setTimeout(함수, 시간) : 일정 시간 후 함수 실행
  2. setInterval(함수, 시간) : 시간 간격마다 함수 실행
  3. clearTimeout() : 설정된 Timeout 함수를 종료
  4. clearInterval() : 설정된 Interval 함수를 종료

아래의 예시를 실행시키면서 타이머 함수를 확인해보자!

<!--index.html-->
<h1>Hello World</h1>
  //setTimeout
  const timeoutTimer = setTimeout(() => {
    console.log('Hun!');
  }, 3000); // ms단위, 3초후 Hun!을 출력


  // h1 태그를 클릭 시 clearTimeout이 실행
  // 3초 전에 h1 태그를 클릭 시 'Hun!'이 출력되지 않는다.
  const h1El = document.querySelector('h1');
  h1El.addEventListener('click', () => {
    clearTimeout(timeoutTimer);
  });


  // setInterval
  const intervalTimer = setInterval(() => {
    console.log('Hun!');
  }, 3000); // ms단위, 3초마다 실행

  // h1 태그를 클릭 시 clearInterval 실행
  // 3초 전 혹은 3초 이후 h1 태그 클릭 시 'Hun!'이 더 이상 출력되지 않는다.
  const h1El2 = document.querySelector('h1');
  h1El2.addEventListener('click', () => {
    clearInterval(intervalTimer);
  });

9. 콜백(callback)

함수의 인수로 사용되는 함수이다. 실행위치를 보장하는 용도로 많이 사용한다.

  function timeout(callback) {
    setTimeout(() => {
      console.log('Hun!');
      callback();
    }, 3000);
  };

  // callback함수, 실행을 보장해준다
  timeout(() => {
    console.log('Done!');
  });

위의 예시코드에서 'Done!'을 출력시키기 위해 인수로 화살표 함수를 넣어준다.
timeout 함수 내부에서 인수를 받아줄 매개변수 callback을 만들어준다.
이후 실행을 보장하고 싶은 장소에 매개변수를 작성하고 함수를 호출하듯이 소괄호를 써준다.
익명함수가 callback으로 들어가게 되고 그 callback으로 매개변수는 호출되지 않은 함수라 할 수 있다.
이를 실행을 보장하고 싶은 장소에 함수를 실행해주는 것이다.

7. 생성자 함수(prototype)

  1. 멤버(Member) : 속성 + 메소드
  2. 리터럴 방식 : 특정 기호로 데이터를 만드는 방식 ex) "", { }, [ ]
  3. 인스턴스 : new라는 키워드를 통해서 생성자 함수로 실행한 결과를 반환해서 할당된 변수
  4. prototype : 메모리를 효율적으로 관리해주기 위해서 사용, 메모리에 딱 한 번 만들어진다.
  5. 생성자 함수 : new로 생성하는 함수, 파스칼 케이스로 작성!
  6. class : prototype을 사용해서 new라는 키워드와 함께 생성자 함수로 인스턴스를 만들어내는 개념
  7. this : this가 소속되어있는 함수가 실행되는 객체데이터를 지칭한다.

예제를 통하여 각 개념이 무엇인지 알아보자!

  const Hun = {
    firstName: 'SeungHun',
    lastName: 'Byeon',
    getFullName: function () {
      return `${this.firstName} ${this.lastName}`
    }
  };

  console.log(Hun.getFullName());

  // 리터럴 방식 
  // class 
  function User(first, last) {
    this.firstName = first;
    this.lastName = last;
  }

  // prototype 
  User.prototype.getFullName = function () {
    return `${this.firstName} ${this.lastName}`
  }


  // 생성자 함수 : User
  // 인스턴스 : Huun, amy, neo
  const Huun = new User('Seunghun', 'Byeon');
  const amy = new User('Amy', 'Clarke');
  const neo = new User('Neo', 'Smith');


  // 아래의 메소드들은 전부 한 번만 만들어진 함수를 참조한다
  console.log(Huun.getFullName());
  console.log(amy.getFullName());
  console.log(neo.getFullName());

  console.log(Huun);
  console.log(amy);
  console.log(neo);

8. this

this : this가 소속되어있는 함수가 실행되는 객체데이터를 지칭한다.

  • 일반(Normal) 함수는 호출 위치에 따라 this 정의!
  • 화살표(Arrow) 함수는 자신이 선언된 함수 범위에서 this 정의!
  const hun = {
    name: 'SeungHun',
    normal() {
    // normal: function () {
      console.log(this.name);
    },
    arrow: () => {
      console.log(this.name);
    }
  }
  hun.normal();	// SeungHun
  hun.arrow();	// 


  const amy = {
    name: 'Amy',
    normal: hun.normal,
    arrow: hun.arrow
  }
  amy.normal();	// 	Amy
  amy.arrow();	// 

  // prototype이용한 this
  function User(name) {
    this.name = name;
  }
  User.prototype.normal = function () {
    console.log(this.name);
  }
  User.prototype.arrow = () => {
    console.log(this.name);
  }

  const Huun = new User('SeungHun');
  Huun.normal();	// SeungHun
  Huun.arrow();		// 


  const timer = {
    name:'Hun!!',
    timeout: function () {  // 함수 범위
      setTimeout(() => {
        console.log(this.name);
      }, 2000)
    }
  }
  timer.timeout();	// 	2초 후 Hun!! 출력

9. ES6 Classes

prototype을 class 문법으로 바꿔보자!

  // prototype
  
  // function User(first, last) {
  //   this.firstName = first;
  //   this.lastName = last;
  // }

  // User.prototype.getFullName = function () {
  //   return `${this.firstName} ${this.lastName}`
  // }
  
  // class
  class User {
  // constructor: function(first, last) {
  constructor(first, last) {
    this.firstName = first;
    this.lastName = last;
  }
  getFullName() { // prototype을 사용하지 않아도 만들 수 있는 장점이 있다.
    return `${this.firstName} ${this.lastName}`
  }
}


  const Huun = new User('Seunghun', 'Byeon');
  const amy = new User('Amy', 'Clarke');
  const neo = new User('Neo', 'Smith');


  console.log(Huun);
  console.log(amy.getFullName());
  console.log(neo.getFullName());

10 . 상속(확장)

새로운 클래스로 확장(상속)할 수 있고 super를 사용하여 새로운 클래스가 확장할 클래스에서 요구되는 인수들을 실행 부분에서 값들을 담아 실행한다.
추가적으로 매개변수를 추가하여 사용할 수 있다.

  class Vehicle {
    constructor(name, wheel){
      this.name = name;
      this.wheel = wheel;
    }
  }

  const myVehicle = new Vehicle('운송수단', '2');
  console.log(myVehicle);

  // 새로운 클래스로 확장 or 상속
  class Bicycle extends Vehicle {
    constructor(name, wheel) {
      // super는 Vehicle을 의미
      super(name, wheel);
    }
  }

  const myBicycle = new Bicycle('삼천리', 2);
  const daughtersBicycle = new Bicycle('세발', 3);
  console.log(myBicycle);
  console.log(daughtersBicycle);


  // 진정한 의미의 확장의 예
  // 정의되어져 있는 기능을 따로 작성하지 않고 Car에서 사용
  // super라는 함수를 실행하여 super가 Vehicle클래스로 실행될 수 있게
  // Vehicle클래스가 요구하는 인수들을 Car 클래스가 실행되는 부분에서 name, wheel을 담아 Vehicle을 실행
  // 추가적으로 license를 매개변수로 받아 사용
  class Car extends Vehicle{
    constructor(name, wheel, license){
    super(name, wheel);
    this.license = license;
    }
  }
  const myCar = new Car('벤츠', 4, true);
  const daughtersCar = new Car('포르쉐', 4, false);
  console.log(myCar);
  console.log(daughtersCar);
profile
잘 할 수 있는 개발자가 되기 위하여

0개의 댓글