ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 📝 JavaScript 기초 강좌 기록 (상)
    SOJU 2기 🍾 2023. 4. 25. 18:17

    이미지를 클릭하면 강의 플레이리스트로 이동한다.

     

     

    서론

    3주 차(1)가 밝았다! ☀️

    (상) 편은 1강부터 9강까지의 강의를 듣고 새롭게 알거나 잘못 알고 있었던 것 등 정보들을 기록했다.

     

     


     

     

    자바스크립트의 역사

    자바스크립트의 역사는 ECMAScript 문서의 등장부터 흥미로워진다. (ECMAScript : 언어의 문법적인 사항들을 정리해 둔 문서)

    1997년 초판을 시작으로 1년마다 새 판이 출판되다가 2000년도 당시 점유율 95%를 차지하던 IE, 마이크로소프트사가 표준안 참가를 거부하게 되면서 표준안 작업이 더뎌지게 된다.

     

    그러던 와중 2004년 모질라 사에서 Firefox 브라우저를 출시.

    마이크로소프트 - 모질라 - 넷스케이프 3사가 표준안을 두고 엎치락뒤치락하게 된다. 

    그 사이 개발자들은 ... 표준안이 정해지지 않았으니 한 프로그램을 만들 때 모든 브라우저에 맞도록 각각의 버전을 만들어야 했다. (🤮)

     

    계속해서 엎치락 뒤치락 어떻게 할 거냐~ 지지부진되고 있는 중 획기적인 것들이 등장한다.

    1. AJAX Asynchronous JavaScript and XML : 비동기적으로 서버에서 데이터를 받아오고 처리할 수 있도록 도와주는 시스템

    2. 개발자 커뮤니티 등에서 JQuery 같은 라이브러리 등장(API) : 더 이상 다른 브라우저들의 구현상황을 신경 쓰지 않아도 되기 위해 

    3. 2008년 드디어! 구글 Chrome 출시 : JS의 실행속도가 굉장히 빠른 JIT 컴파일러를 사용한 V8 엔진이 포함.

    특히나 구글 크롬의 등장은 다른 브라우저들에게 있어 커다란 자극제가 되어주었고, 결국 표준안을 만들기로 합의한다. (서로 윈윈!)

     

    2009년 드디어 ECMAScript5 !! 가 출판 이어서 2015년에는 6판이 출판되었다.

    라이브러리의 도움 없이 Web API 만으로도 모든 브라우저에서 잘 동작하는 스크립트를 만들 수 있게 되었다.

     

     

     

     

    <script... async  vs defer >?

    html 파일에 script 파일을 연결할 때, <script> 요소를 사용한다.

    <script> 요소의 위치, 속성의 유무에 따라 안전성과 효율성의 차이가 생기기 때문에 각각의 차이를 잘 이해하자.

    (기본 : html 코드를 위에서 아래로 한 줄씩 분석한다.)

     

    1. <head> 안 <script> 의 경우

    script 요소를 만나면 한줄씩 분석하던 걸 멈추고, 연결되어 있는 js 파일 다운을 시작한다. 

    다운이 끝나면 실행 -> 그 다음에 다시 한 줄씩 분석 시작.

    ❗️단점 : js 파일이 크거나 인터넷이 느리다면 페이지 로드 시간이 오래 걸린다.

     

    2. <body>의 맨 마지막에 <script>를 사용하는 경우

    js를 다운로드하지 않더라도 페이지 콘텐츠를 모두 볼 수 있다. (js 다운은 가장 마지막에 이루어지기 때문에)

    ❗️단점 : 자바스크립트에 굉장히 의존적인 웹사이트의 경우 (= 의미 있는 콘텐츠가 자바스크립트에 포함되어 있는 경우) 사용자가 정상적인 사이트를 볼 때까지 오랜 시간을 기다려야 한다. (js 다운로드하는 시간 + js 실행하는 시간)

     

    🤔 js 다운과 실행, html 코드 읽기가 같이 이루어질 수는 없는 걸까? (-> 속성을 사용한다)

    3. <head> 안 async 속성 값 사용

    <script src=".js" async></script>

    (async 는 boolean 타입의 속성값으로 선언하는 것만으로도 true 값을 가진다.)

    - script 요소를 만나면 연결된 js 파일 다운을 시작하면서! 멈추지 않고! 한 줄씩 분석을 이어간다. 

    - js 파일의 다운로드가 완료되면 분석을 잠시 멈추고, js 파일을 실행한다.

    - 실행 후 분석이 다시 시작된다.

     

    장점 : 다운로드하는 시간 절약 가능

    ❗️단점 :

    - 예를 들어 html의 DOM 요소를 사용하는 js 파일의 경우, 원하는 요소가 아직 정의되어 있지 않을 수 있어 위험 (html 분석이 다 끝나기 전에 js파일이 실행되므로) 

    - js 파일 실행 시간으로 사이트가 멈출 수도 있기 때문에 시간이 오래 걸릴 수 있다.

    - 복수의 js 파일을 사용하는 경우, 다운로드가 끝난 순서대로 실행시키기 때문에 순서가 중요한 js 파일이라면 문제가 생길 수 있다.

     

    4. <head> 안 defer 속성 값 사용

    <script src=".js" defer></script>

    defer 속성을 확인하면 js 파일 다운 명령을 내린다. html을 모두 분석 후 바로 js 파일을 실행한다.

    복수의 js 파일을 사용하는 경우, 다운로드는 모두 함께 하고 써져 있는 순서대로 실행된다.

     

    => 즉, defer 속성을 사용하는 게 가장 안전하고 효율적이다. 

     

    +) "use strict" (ECMAScript5에서 추가)

    바닐라 자바스크립트의 경우 js 파일의 가장 위에 정의해 주면 좋다.

    왜? 자바스크립트는 유연한 언어이기 때문!

    유연한 언어 = 위험하다는 특징을 갖고 있다. 선언하지도 않은 변수에 값을 할당한다든지...라는 비상식적인 상황을 막아준다.

    또한 엔진이 더 효율적이고 빠르게 분석할 수 있게 한다.

     

     

     

     

    Object

    한두 가지 이상의 데이터를 묶어둔 것 (예: 함수, 리스트...)

    (data type: number, string, boolean, null, undefined, symbol.. 작은 단위의 데이터들을 제외한 모든 것)

     

    ✨중요

    object를 변수에 할당했을 때, 변수는 할당한 object 그 자체를 가지고 있는 게 아니다.

    변수가 갖고 있는 값은 (어딘가 따로 저장되어 있는) object를 가리키는 주소(reference)이다.

     

    ❗️값을 할당하는 변수와 달리 오브젝트를 할당한 변수, 그리고 그 변수를 다른 변수에 할당했을 경우 :

    가리키는 주소를 복사한 것이므로 두 변수 모두 오브젝트 원본을 가리키는 주소를 담고 있다.

    어떤 쪽이든 수정하면 모두 값이 변경되는 걸 확인할 수 있다.

     

    ❗️object 안에 key의 유무를 확인하는 방법

    console.log("name" in burger); // true
    console.log("random" in burger); // false

     

     

     

     

     

    Function

    왜 함수를 사용할까?

    반복해서 사용하는 혹은 수행하는 로직이 있다면 그때그때 또 똑같은 걸 쓰는 게 아니라 함수로 만들어서 호출 -> 재사용할 수 있기 때문

     

    Function is object in JS!!! 

    잊지 말아야 할 사실. 함수는 object이다. => object의 특징들을 가지고 있다. 

    즉, 함수 이름(like 변수)에는 함수가 정의된 곳을 가리키고 있는 주소(reference)가 들어있다.

    1. 변수를 선언함과 동시에 함수를 할당한다. 

    2. 변수이름(); 로 함수를 호출할 수 있다. (실행)

    3. 또 다른 변수를 선언하고, 변수이름을 할당한다. 

    4. 또 다른 변수(); 로 할당되어 있는 값(주소)을 통해 함수를 호출한다 (실행)

     

     

     

     

     

     

    Class

    클래스는 다양한 object를 만들기 위한 청사진(틀)이다.

    무언가를 설명하기 위해 필요한 데이터가 class라는 틀 안에 들어가면 object가 된다.

     

    1) 클래스 선언

    class Person {
      // constructor 생성자
      constructor(name, age) {
        // fields
        // 전달된 데이터 바로 할당
        this.name = name;
        this.age = age;
      }
    
      // methods
      speak() {
        console.log(`${this.name}: hello!!`);
      }
    }

     

    2) 오브젝트 생성

    const burger = new Person("burger", 72);
    console.log(burger.name);
    console.log(burger.age);
    burger.speak();

     

    3) Getter와 Setter

    예를 들어 사용자의 나이를 입력받아야 할 때, 사용자가 -1라고 잘못 썼다고 생각해 보자.

    -1살...? 그런 건 존재하지 않는다.

    이러한 상황을 방지하기 위해 getter와 setter를 사용한다.

     

    4) public, private

     

    5) 상속과 다양성

    class 끼리 상속받을 수 있다. 

    class Shape {
      constructor(width, height, color) {
        this.width = width;
        this.height = height;
        this.color = color;
      }
    
      draw() {
        console.log(`drawing ${this.color} color!!`);
      }
    
      getArea() {
        return width * this.height;
      }
    }

    Shape라는 클래스가 존재한다고 했을 때, Shape를 상속받아 부분적으로만 추가 변경 하고 싶을 때 어떻게 해야 할까?

    // 자동적으로 Shape이 Rectangle에 포함됨
    class Rectangle extends Shape {}
    class Triangle extends Shape {
      draw() {
        super.draw(); // 부모의 draw가 출력
        console.log("🔺");
      }
    
      getArea() {
        return (width * this.height) / 2;
      }
    }

    extends를 사용하면 된다!

     

    +) class... 어떻게 해야 효율적으로 사용할 수 있을까?

    클래스 안에 모든 정보, 함수를 담으려고 하지 말자.

    콜백함수를 받아오는 등 적절히 이용, 조립하여 사용하는 편이 수정, 추가, 삭제에도 편리하다.

    // * 클래스 (다양한 오브젝트를 만들기 위한 청사진!)
    // 생성이 되면 counter라는 변수가 있고 0부터 시작한다.
    // Counter라는 클래스에는 자체적으로 counter라는 변수가 있고, 0으로 초기화된다.
    class Counter {
      constructor(runEveryFiveTimes) {
        this.counter = 0;
        this.callback = runEveryFiveTimes;
      }
    
      // class 내에서 함수 선언할 때는 function 안써도 된다
      increase() {
        this.counter++;
        console.log(this.counter);
        // 1번째 방법 if문 안에서 출력 console.log() (문제: 출력이 아니라 다른 방법으로 보여주고 싶다면? yo말고 다른 걸 출력하고 싶다면? -> 즉, 컨트롤할 수 없다)
        if (this.counter % 5 === 0) {
          // 2번째 방법 콜백함수 사용. (장점 : 원하는 기능 추가 변경 등 손쉬움.)
          // runIf5Times(this.counter);
          this.callback && this.callback(this.counter); // undefined가 아닐 때 실행
        }
      }
    }
    
    // constructor 실행 > counter = 0 초기화
    function printSomething(num) {
      console.log(`wow! ${num}`);
    }
    
    function alertNum(num) {
      alert(num);
    }
    
    // class 에 원하는 콜백함수를 전달하는 방법
    const coolCounter = new Counter(printSomething);
    // ? 만약 클래스를 생성할 때 콜백함수를 전달하지 않는다면 (undefined) -> TypeError!
    
    // ! 하나의 클래스로 다양한 오브젝트를 만들어서 서로 다른 기능을 수행하는 오브젝트를 만들 수 있다 -> 재사용률이 높아진다!
    const printCounter = new Counter(printSomething);
    const alertCounter = new Counter(alertNum);
    
    coolCounter.increase(); //1
    coolCounter.increase(); //2
    coolCounter.increase(); //3
    coolCounter.increase(); //4
    coolCounter.increase(); //5 > 출력
    coolCounter.increase();
    coolCounter.increase();
    coolCounter.increase();
    coolCounter.increase();
    coolCounter.increase(); // alert 10

     

     

     

     

     

     

     

     

     

     

     

     

     

    댓글

Designed by Tistory.