자바스크립트에서 알아야 할 필수 개념들

제로초님 강의 정리 https://www.youtube.com/watch?v=b4LxIniE9-M

함수, 객체

자바스크립트는 객체지향 or 함수형 프로그래밍도 되는 멀티 패러다임 언어이므로 함수와 객체를 자세히 알아두자

객체: 현실의 사물을 프로그래밍에 반영한 것

객체 = (객체, 배열, 함수) 셋 모두 객체임.

함수: 자바스크립트의 꽃, 자바스크립트는 모든것을 함수로 할 수 있다.

자바스크립트에서는 함수도 하나의 값으로 사용. 객체의 속성값이 함수인 것 = 메소드

  var a = {
    info: function(){    < 속성명info의 값은 함수로 선언되어있고 이 함수는 메서드이다.
      return;
    }
  }

배열 메서드

배열.map(function(값, 자릿수) { 조건 })

배열.forEach(function(값, 자릿수) { 조건 })

배열의 모든 항목을 반복하면서 조작하는 함수. 매개변수로 함수가 들어가고, 함수안에 배의 항목을 어떻게 조작할지 적어주면 됨.

  var array = [1,2,3];
  array.map(function(x) {
    return x+1;
  }); // [2,3,4]
  array.forEach(function(x, i) {
    alert(x + ':' + i);
  });

map과 forEach의 차이점: map은 바뀐 새 배열을 반환하지만, forEach는 반환하지 않는다. 따라서 forEach보다는 map이 활용성이 더 높다.

배열.reduce(function(이전값, 현재) { 조건 })

배열.reduceRight

  var array = [1, 2, 3, 4, 5];
  array.reduce(function(prev, cur) {
    return prev + cur;
  }); // 15

배열을 왼쪽부터 조건을 적용해 하나의 값으로 만든다. 위의 코드의 조건은 이전 값과 현재 값을 더한 값을 반환하는 거죠? 왼쪽 두 개부터 시작합니다. 이전 값은 1이고 현재 값은 2라서 더하면 3이 됩니다. 그 값이 다시 이전 값이 됩니다. 이제 이전 값은 3이고 현재 값은 3이라서 더하면 6이되고, 다음에는 이전 값이 6이고, 현재 값은 4가 되어서 더하면 10, 마지막으로 이전 값이 10이고 현재 값이 5라서 더하면 15가 됩니다. 최종 결과를 반환합니다. 간단히 말하면 조건에 따라, 1 + 2 + 3 + 4 + 5를 한 겁니다. 오른쪽부터 줄여가고 싶으면 자매품, reduceRight 함수를 사용하시면 됩니다.

배열.filter(function(항목) { 조건 })

  var array = [1,2,3,4,5];
  array.filter(function(x) {
    return x % 2 === 0;
  }); // [2,4]

필터링! 특정 조건에 해당하는 배열만을 걸러내 새 배열로 만듭니다. 역시 매개변수로 있는 함수 안에 조건을 적으면 됩니다. 여기서는 조건이 항목을 2로 나눈 나머지가 0인 것(짝수)만 걸러내라고 되어있네요.

싱글스레드(비동기) : 이벤트 드리븐 프로그래밍

자바스크립트에서 비동기란? 코드상의 순서대로 실행되지 않는 코드! ex) callback 함수

  button.addEventListner('click', 콜백함수(){
    alert('aaaa');
    })

이벤트 리스너에 있는 콜백함수는, 클릭 이벤트가 발생하지 않는 한 실행되지 않는다.

callback, 프로미스, async/await 이해하기

  • 이해하려면, 호풀스택, 이벤트루프, 실행 컨텍스트(자바스크립트 실행순서) 실행 컨텍스트를 이해하면 this 같은것도 이해할수 있음.

이벤트 드리븐 프로그래밍? 버튼 클릭 등 클릭 이벤트(사용자와의 상호작용이 많은 특성상)

프로토타입

자바랑 가장 큰 차이점 자바는 클래스 기반 자바스크립트는 프로토타입 기반 자바의 class 와 자바스크립트의 class(=프로토타입) 는 다르다.

하면서 익숙해지는 개념들

DOM 외우지 마세요, 쓰다보면 외워져요 class 보다 프로토타입을 먼저 알아야함 디자인패턴 -> 책만 한번 보고 내 코딩 스타일을 확인만 해보고, 코딩 하다보면 코드정리 하다보면 알아서 디자인패턴 모양이 된다. 함수영 프로그래밍 -> map, filter, reduce 만 외우자 배열 -> 객체의 일종, 실무에서는 이차원 배열을 많이 다룸.(map, filter, reduce 많이씀)


함수의 범위(scope)

: 함수 안에서 선언된 변수는 해당 함수 안에서만 사용될 수 있다. (지역변수) = 변수는 자신을 감싸고 있는 함수 밖으로 나갈 수 없다.

스코프 체인(scope chain)

: 전역변수와 지역변수 사이의 관계에서 나온 개념 스코프 간의 상하관계를 스코프 체인이라고 한다.

  var name = 'zero';
  function outer() {
    console.log('외부', name);
    function inner() {
      var enemy = 'nero';
      console.log('내부', name);
    }
    inner();
  }
  outer(); //외부 zero 내부 zero
  console.log(enemy); // undefined

inner 함수는 name 변수를 찾기 위해 먼저 자기 자신의 스코프에서 찾고, 없으면 한 단계 올라가 outer 스코프에서 찾고, 없으면 다시 올라가 결국 전역 스코프에서 찾습니다. 다행히 전역 스코프에서 name 변수를 찾아서 ‘zero’라는 값을 얻었습니다. 만약 전역 스코프에도 없다면 변수를 찾지 못하였다는 에러가 발생합니다. 이렇게 꼬리를 물고 계속 범위를 넓히면서 찾는 관계를 스코프 체인이라고 부릅니다.

렉시컬 스코핑(lexical scoping)

: 스코프는 함수를 선언 할 때 생긴다! 호출XX할 때가 아님!!

  var name = 'zero';
  function log() {
    console.log(name);
  }

  function wrapper() {
    name = 'nero';
    log();
  }
  wrapper();

위 결과: nero 호출됨. 전역변수인 name을 함수가 바꿀 수 있었음

  var name = 'zero';
  function log() {
    console.log(name);
  }

  function wrapper() {
    var name = 'nero';
    log();
  }
  wrapper();

위 결과: zero 가 호출됨! 헐 왜?!?! 스코프는 함수를 선언할 때 생긴다고 했죠? log 안의 name은 wrapper 안의 지역변수 name이 아니라, 전역변수 name을 가리키고 있는 겁니다. 이런 것을 lexical scoping이라고 합니다. 함수를 처음 선언하는 순간, 함수 내부의 변수는 자기 스코프로부터 가장 가까운 곳(상위 범위에서)에 있는 변수를 계속 참조하게 됩니다. 위의 예시에서는 log 함수 안의 name 변수는 선언 시 가장 가까운 전역변수 name을 참조하게 됩니다. 그래서 wrapper 안에서 log를 호출해도 지역변수 name=’nero’를 참조하는 게 아니라 그대로 전역변수 name 의 값인 zero가 나오는 겁니다.

전역변수를 만드는 일은 지양하는 이유는 변수가 섞일 수 있기 때문입니다.

변수가 섞이지 않도록 하는 해결방법?!

  • 네임스페이스를 만든다. 만드는 방법 1. 전역변수 대신, 한번 함수 안에 넣어 지역변수로 바꾸기. .2. 객체안의 속성으로 바꾸기
    var obj = {
      x: 'local',
      y: function() {
        alert(this.x);
      }
    }
    

    위 처럼 하면 obj.x, obj.y() 이렇게 접근해야 하기 때문에 다른 사람과 섞일 염려가 없죠. obj를 통째로 덮어쓰지 않는 이상은요. 전역변수를 하나로 최소화해서 변수가 겹칠 우려도 최소화하는 거죠. 하지만, 누군가 고의적으로 obj.x = 'hacked'; 로 속성값을 수정할 수도 있다.

이를 방지하기 위해서 아래와 같은 방법을 이용한다.

  var another = function () {
    var x = 'local';
    function y() {
      alert(x);
    }
    return { y: y };
  }
  var newScope = another();

조금 복잡하지만 위와 같이 하면 됩니다. another(); 하는 순간 return에 의해 { y: function () { alert(x) } }; 가 newScope에 저장됩니다. 이제 newScope라는 네임스페이스를 통해서 y에 접근할 수 있습니다. x는 접근할 수 없죠. 위처럼 함수로 감싼 후 return을 통해 공개할 변수(y)만 공개하고 비공개할 변수(x)는 비공개하는 방법을 취할 수 있습니다. 즉, return하는 변수는 공개 변수고, 다른 것은 비공개 변수인거죠.

위의 코드를 간략하게 바꾸면

  var newScope = (function () {
    var x = 'local';
    return {
      y: function() {
        alert(x);
      }
    };
  })();

(function() {})(); 구문을 볼 수 있는데,, 이같은 형태를 IIFE(즉시 호출 함수 표현식)이라고도 하고, 모듈 패턴이라고도 하는데, 함수를 선언하자마자 바로 실행시켜버린다! = 모듈패턴 많은 라이브러리가 이 구문을 활용하고 있습니다. 비공개 변수가 없는 자바스크립트에 비공개 변수 기능을 만들어주기 때문이죠. 이 패턴은 꼭 기억하고 있어야합니다!

실행 컨택스트

쉽게말하면, 코드의 실행 문맥. 코드의 실행 환경