본문 바로가기

2024내일배움캠프/TIL

[TIL] 1/2 JS문법다지기(ES6)_2

  •  if문 줄이기

    • and 조건(&&)
      • if(x > 0){
           consol.log("x는 양수입니다.");
        }
      • (x > 0) && consol.log("x는 양수입니다.");

    • or 조건(||)
      • let y;
        let z = y || 20;
        -> y가 undefined면 기본값 20으로 세팅해달라는 뜻
  • falsy한 값 : 0, "", null, undefined, NaN, false
  • 객체
    • 객체이름.key로 속성에 접근
    • entries : key 와 value를 묶어서 배열로 만든 배열(2차원 배열)
      let entries = Object.entries(person);
    • assign : 객체 복사
      let newPerson = {}
      Object.assgin(newPerson, person, {age: 31});
      -> 수정하고 싶은 데이터는 {}를 이용해 복사하며 수정한다.
    • JSON.stringify(비교대상1) === JSON.stringify(비교대상2)
      객체와 같은 크기가 커서 값을 저장하지 않고 주소값을 저장하는 것을 비교하고 싶다면
      json에서 제공하는 문자열화 시켜주는 메소드를 사용할 수 있다.
    • ...{병합시킬객체1}, ...{병합시킬객체2} : 객체 병합
let person1 = {
    name: "홍길동",
    age: "30",
};

//person2 별도 공간에 대한 주소
let person2 = {
    gender: "남자",
};

// ... : spread oprator
let perfectMan = { ...person1};
// 이라고 하면 perosn1의 값만 쭉 들어오게 된다
let perfectMan1 = {...person1, ...person2};
// 이라고 하면 두개가 병합되어 perfectMan1에 저장된다.
  • 배열
    • 크기 지정
      let number : new Array(5)
      -> 5개의 비어있는 배열 생성
    • push() : 배열 뒤에 삽입
    • pop() : 마지막 요소 삭제
    • shift() : 첫번째 요소 삭제
    • unshift() : 첫번째에 요소 삽입
    • splice : 특정 위치 삭제 후 요소 삽입
      fruits.splice(1(첫번째 위치부터),1(1개를 삭제하고), "포도"(포도를 삽입해줘))
    • slice : 배열에서 일부분 추출 후 새로운 배열 생성
      let slicedFruits = fruits.slice(1, 2); 
      -> 2번째 요소부터 3번째 요소까지를 뽑아서 새로운 배열로 만들어줘
  • 콜백함수 : 매개변수 자리에 함수를 넣는 것
    • numbers.forEach(function(item){
          console.log('item입니다 -> ' + item);
      });
    • map : 기존의 배열을 가공하여 새로운 배열 생성
      새 배열을 담을 배열 지정해주고 리턴값이 존재
      항상 원본 배열 길이만큼이 return 된다
      let newNumbers = numbers.map(function(item){
          return item * 2;
      });
    • filter
      배열 중 원하는 값만 걸러서 새로운 배열에 넣어서 반환
      let filterdNumbers = numbers.filter(function(item){
          return item === 5;
      });
    • find
      조건에 해당하는 첫번째 요소만 반환
      let result = numbers.find(function(item){
          return item > 3;
      })
  • for ~ in문
    객체의 속성을 출력하는 문법
    let person = {
        name: "John",
        age: 30,
        gender: "male",
    };
    for(let key in person){
        console.log(key + ": " + person[key]);
    }
  • 단축 속성명 : property shorthand
const name = "abc"
const newage = 30;

// 객체에서 key와 value의 이름이 같을 수 있다.
// 그럴 때 하나로 적어줘도 된다.
const obj = {
	name, 
    age: newage
 }
 
 //age도 이름이 같다면
 const obj = {name, age} // 배열같이 보이지만 객체이다
  • 전개 구문 : spread operator
    destructuring과 함께 가장 많이 사용되는 es6문법 중 하나
    • let arr = [1, 2, 3] // 4를 추가하고 싶을 때 push를 사용해도 되지만
      let newArr = [...arr, 4] // 새로운 배열을 생성하면서 추가해줄 수 있다.
      여기서 ...란 배열 안에 있던걸 꺼내서 다시 넣어준다라고 생각하면 된다
    • 객체에서도 가능하다
      let user = {
           name: "nbc",
           age: 30,
      };
      let user2 = {...user}
      -> user와 user2는 같다
  • 나머지 매개변수 (rest parameter)
    ...args를 적음으로 뒤에 추가로 매개변수가 들어올 수 있음을 알려주는 것
    ...가 없으면 배열로 추가됨 ...를 적어야 같은 매개변수로 인식
    • function exampleFunc(a, b, c, ...args){
          console.log(a, b, c);
          console.log(args);
      }
      exampleFunc(1, 2, 3, 4, 5, 6, 7);
  • 일급개체로써의 함수
    • 변수에 함수 할당 가능
    • 함수를 인자로 다른 함수에 전달 가능
      • 콜백함수
      • 고차함수
    • 함수를 반환할 수 있다
  • 객체 안에 함수 넣을 수 있다
  • 배열의 요소로 함수 할당 가능
const myArr = {
    function(a, b){
        return a + b;
    }, // 0번째 요소
    function(a, b){
        returna - b;
    }, // 1번째 요소
};

console.log(myArr[0](1, 3));
console.log(myArr[1](10, 3));
  • map
    key / value
    키가 정렬된 순으로 저장됨
    • 선언 : const myMap = new Map();
      할당 : myMap.set('key', 'value');
      검색 : myMap.get('key');
    • 반복
      반복문을 사용하지 않아도 iterator로 반복하는 기능을 가진 메소드
      • keys()
        console.log(myMap.keys());
        for(const key of myMap.keys()){
            console.log(key);
        }
      • values()
        console.log(myMap.values());
        for(const value of myMap.values()){
        console.log(value);
        }
      • entries()
        console.log(myMap.entries());
        for(const entry of myMap.entries()){
            console.log(entry);
        }
  • set
    고유한 값을 저장하는 자료구조 = 값이 중복되지 않는다
    값만 저장한다. 키는 저장하지 않는다. 
    • 선언 : const mySet = new Set();
      할당 : mySet.add('value')
    • 반복 : iterator
      value 값만 들어가기 때문에 values()만 사용
      • for(const value of mySet.values()){
            console.log(value);
        }
  • 얕은 복사
    객체도 복사할 수 있지만 사실상 객체의 파라미터 값이 복사되는거고,
    객체는 가변이기 때문에, 복사한 객체에서 값을 변경하면 원객체의 값에 영향을 미친다
    -> 따로 함수로 빼서 객체 하나하나를 돌면서 값을 복사해줌으로 얉은 복사를 할 수 있다.
    하지만 이또한 완벽한 복사는 아니다. 객체 안의 객체는 또 주소값을 복사하기 때문이다.

var copyObject = function(target){
    var result = {};

    for (var prop in target){
        result[prop] = target[prop];
    }
    return result;
}

var user = {
    name: "bob",
    gender: "male",
};

var user2 = copyObject(user);
user2.name = "david";
  • 깊은 복사 : 얉은 복사의 한계를 극복하기 위해 모든 값을 하나하나 다 찾아서 복사하는 방법
    -> 재귀적으로 수행
var copyObjectDeep = function(target){
    var result = {};
    if(typeof target === 'object' && target !== null){
        for (var prop in target){
            result(var prop in target){
                result[pop] copyObjectDeep(target[prop]);
            }
        }else{
            result = target;
        }
    }
    return result;
}
  • null
    • null의 type of하면 object가 나오는데 이건 js의 오류
    • null 값과 undefined는 똑같이 없는 값이기 때문에 null == undefined
      즉, 동등연산자로 출력해보면 true 값을 출력하는걸 알 수 있다
  • js는 코드의 실행이 콜스택에 쌓여서 순서대로 실행된다.
    전역을 읽어내려오다가[전역] - 함수1 호출을 만나서[전역-함수1] - 함수1로 들어갔는데 함수2 호출을 만나고[전역-함수1-함수2] - 함수2로 들어가서 수행하고 나오고[전역-함수1] - 함수1도 다 수행하고 나오고[전역]- 전역도 끝까지 수행하고 끝
  • 실행 컨텍스트 객체의 실체(= 담기는 정보)
    -> 결국, 실행 컨텍스트를 생성할 때, VE에 정보를 먼저 담은 다음,
         이를 그대로 복사해서 LE를 만들고 이후에는 주로 LE를 활용한다
    • VariableEnvironment
      • 현재 컨텍스트 내의 식별자 정보(= record)를 가지고 있다
      • 외부 환경 정보(= outer)를 가지고 있다
      • 선언 시점 LexicalEnvironment의 snapshot
    • LexicalEnvironment
      • VariableEnvironment와 똑같은데, 변경사항을 실시간으로 반영한다
      • 현재 컨텍스트 내의 식별자 정보(= record)를 가지고 있다
        -> 이 record의 수집 과정이 호이스팅
      • 외부 환경 정보(= outer)를 가지고 있다
      • 호이스팅
        현재 컨텍스트와 관련된 코드의 식별자 정보들이 저장(수집)
        실행되는것은 아니나 수집되어 위로 끌어올려져서 실행 순서가 바뀔 수 있다
        -> 예상한 값과 다른 값을 얻게 될 수 있다
        • 변수 선언부만 끌어올려진다
        • 마찬가지로 함수 선언문도 전체가 끌어올려진다
        • 함수 표현식은 변수 부분만 끌어올려진다
    • ThisBinding
      • this 식별자가 바라봐야할 객체
    • 함수 정의
      • 함수 선언문 : 전체가 호이스팅되기 때문에(= 전체 코드에 영향) 위험
        함수 정의부만 존재하고 할당 명령은 없는 경우
        function a(){-------}
        a();
      • 함수 표현식 : 선언부만 호이스팅되기 때문에(= 선언 이후 코드에만 영향)
                             복잡하거나, 협업하는 경우 표현식을 사용하기
        선언한 함수를 별도 변수에 할당하는 경우
        var b = function(){------}
        b();
    • 스코프 : 식별자에 대한 유효범위
    • 스코프 체인 : 식별자의 유효범위를 안에서부터 바깥으로 차례로 검색해나 가는 것
      • 각각의 실행 컨텍스트는 LE 안에 record와 outer를 가지고 있고,
        outer 안에는 그 실행 컨텍스트가 선언될 당시의 LE 정보가 다 들어있으니,
        scope chain에 의해 상위 컨텍스트의 record를 읽어올 수 있다.
    • this는 실행 컨텍스트가 생성될 때 결정(= this를 bind한다)
      -> this는 함수를 호출할 때 결정된다
      • 전역 공간에서의 this : 전역 객체
      • 메서드로서의 호출에서의 this: 호출한 주체를 가리킨다
        구분은 .과 []
      • 함수로서의 호출에서의 this : 전역 객체
    • this 우회법
      • 변수에 할당하기

var obj1 = {
    outer: function () {
        console.log(this); //(1) outer

        //AS-IS
        var innerFunc1 = function () {
            console.log(this); //(2) 전역객체
        }
        innerFunc1();

        // TO-BE
        var self = this;
        var innerFunc2 = function () {
            console.log(self); //(3)outer
        };
        innerFunc2();
    }
};

//메서드 호출 부분
obj1.outer();
  • 화살표함수(this를 바인딩하지 않는 함수) 사용하기
    일반 함수와 화살표 함수의 가장 큰 차이: this binding 여부 
var obj = {
    outer: function(){
        console.log(this); //(1)obj
        var innerFunc = () => {
            console.log(this); //(2)obj-this binding과정이 생략됐기 때문에 여전히 obj를 들고 있다
        };
        innerFunc();
    }
}
obj.outer();
  • 콜백함수의 this는 무조건 전역객체를 바라본다
    지정해주지 않는 이상.
  • 생성자 함수 내부에서의 this 
var Cat = function(name, age){
    this.bark = 'meow';
    this.name = name;
    this.age = age;
};

var choco = new Cat('초코', 7); //this: choco
var nabi = new Cat('나비', 5); //this: nabi

 

 

 

1주차 15강부터 3주차 11강까지 들으면서 기록한 강의 내용들

새로 알게 되거나 / 나중에 필요할 것 같은 부분들 위주로 적었다

호이스팅 부분을 다 이해한 줄 알았는데 한번더 나오는 예제에서 잘 이해가 안돼서 강의를 멈추고 혼자 vscode에 예제를 적어보니 이해했다.

var a = 1;
var outer = function() {
    var inner = function(){
        console.log(a);
        var a = 3;
    };
    inner();
    console.log(a);
};
outer();
console.log(a);

이 예제였는데, 처음에 a의 출력값이 undifined인게 이해가 가지 않았다.

전역변수로 선언해주고 할당했기 때문에 1이 될 줄 알았다

다시 찬찬히 살펴보니 inner 함수 안에서 var a가 다시 선언과 할당되었기 때문에 이 함수 내에서 호이스팅이 된 것

즉, console.log(a)위로 var a;가 올라간 것이다. console.log이후에 할당이 나오기 때문에 undefined 되었다.

inner 함수를 나와서는 전역변수 a의 값이 출력되고 마찬가지로 outer를 나와서도 전역변수 a의 값이 출력되었다.

 

c++과 비슷한 점도 있고 다른점도 있어서 그 차이를 보면서 배우는게 재미가 있다.

어려운 부분도 있지만 이해가 잘 가지 않는 부분은 강의를 다시 돌려보거나 혼자 작성해가면서 이해해서 뿌듯하기도 하다.