3주차 TIL & 회고

강성일·2023년 4월 30일
0
post-thumbnail

✅ TIL


⚙️ 함수 선언문


function myFunc(theArr) {
  theArr[0] = 30;
}

const arr = [45];

console.log(arr[0]); // 45
myFunc(arr);
console.log(arr[0]); // 30


⚙️ 함수 표현식


const square = function (number) { 
  return number * number;
}
const x = square(4); // `x` 의 값은 16 입니다.


⚙️ 호이스팅


JS에서 변수와 함수를 선언하는 위치와는 상관없이 스코프(scope)의 최상위로 끌어올려지는 것


hoisting();

function hoisting() {
  console.log("hi");
}

위 코드는 아래와 같이 해석된다.


function hoisting() {
  console.log("hi");
}

hoisting();

위와 같이 변수나 함수 선언문에는 호이스팅이 발생한다.

함수 표현식에서는 함수의 이름만 호이스팅되고, 함수 표현식 자체는 끌어올리지 않는 것 유의하자.

추가로, let과 const를 이용하여 변수를 선언하면, 호이스팅이 발생하지 않아 스코프를 더욱 명확하게 관리할 수 있다.



🔥 복습



⚙️ Scope.


describe("scope 대해서 학습합니다.", function () {
 
  it("함수 선언식(declaration)과 함수 표현식(expression)의 차이를 확인합니다.", function () {
    let funcExpressed = "to be a function";

    expect(typeof funcDeclared).to.equal("function");
    expect(typeof funcExpressed).to.equal("string");

    // 둘에 식 차이는 순서에 영향을 받는 것.
    // 함수 선언식은 순서에 영향을 받지 않고, 함수 표현식은 순서에 영향을 받는다. (호이스팅)

    // 함수 선언식
    function funcDeclared() {
      return "this is a function declaration";
    }

    // 함수 표현식
    funcExpressed = function () {
      return "this is a function expression";
    };

    const funcContainer = { func: funcExpressed };
    expect(funcContainer.func()).to.equal("this is a function expression");

    funcContainer.func = funcDeclared;
    expect(funcContainer.func()).to.equal("this is a function declaration");
  });

  it("lexical scope에 대해서 확인합니다.", function () {
    // message
    let message = "Outer";

    function getMessage() {
      //
      return message;
    }

    function shadowGlobal() {
      // message
      let message = "Inner";
      return message;
    }

    function shadowGlobal2(message) {
      // message
      return message;
    }

    function shadowParameter(message) {
      // message
      // let message = 'Parameter';
      message = "Do not use parameters like this!";
      return message;
    }

    expect(getMessage()).to.equal("Outer");
    expect(shadowGlobal()).to.equal("Inner");
    expect(shadowGlobal2("Parameter")).to.equal("Parameter");
    expect(shadowParameter("Parameter")).to.equal(
      "Do not use parameters like this!"
    );
    expect(message).to.equal("Outer");
  });

  it("default parameter에 대해 확인합니다.", function () {
    function defaultParameter(num = 5) {
      return num;
    }

    expect(defaultParameter()).to.equal(5);
    expect(defaultParameter(10)).to.equal(10);

    function pushNum(num, arr = []) {
      arr.push(num);
      return arr;
    }

    expect(pushNum(10)).to.deep.equal([10]);
    expect(pushNum(20)).to.deep.equal([20]);
    expect(pushNum(4, [1, 2, 3])).to.deep.equal([1, 2, 3, 4]);
  });

  it("클로저(closure)에 대해 확인합니다.", function () {
    function increaseBy(increaseByAmount) {
      return function (numberToIncrease) {
        return numberToIncrease + increaseByAmount;
      };
    }

    const increaseBy3 = increaseBy(3);
    const increaseBy5 = increaseBy(5);

    expect(increaseBy3(10)).to.equal(13);
    expect(increaseBy5(10)).to.equal(15);
    expect(increaseBy(8)(6) + increaseBy(5)(9)).to.equal(28);
  });

  it("lexical scope와 closure에 대해 다시 확인합니다.", function () {
    // let은 선언. 만약 해당하는 부분을 찾았다면 let을 가져오는게 맞고
    // let이 없이 가져오라고 했다면, 상위 함수에서 let이 선언된 부분을 가져온다.
    
    let age = 27;
    let name = "jin";
    let height = 179;

    function outerFn() {
      let age = 24; // outerFn의 지역 변수
      name = "jimin"; // outerFn '상위' 함수의 지역 변수 <- 선언 기준, 바꾼 거 기준 아님.
      let height = 178;

      function innerFn() {
        age = 26; // outerFn의 지역 변수
        let name = "suga"; // innerFn의 지역 변수
        return height; // outerFn의 지역 변수
      }

      innerFn();

      expect(age).to.equal(26); // <- inner가 outer에서 선언한 age 를 바꿈
      expect(name).to.equal("jimin"); // <- outer가 글로벌 name을 바꿈

      return innerFn;
    }

    // innerFn();  을 실행했다면 outerFn 안에 있는 거니까 undefinded 나옴

    // 이거 innerFn은 위 innerFn 함수랑 다름, 이름만 비슷할 뿐

    const innerFn = outerFn(); // outerFn 함수를 실행해서 innerFn을 반환받았다.
    //const innerFn에 outerFn을 저장해야만 outerFn에서 실행된 innerFn을 사용할 수 있음

    expect(age).to.equal(27); // innerFn이 age를 바꾼 것은 outerFn까지만 영향을 준다.
    expect(name).to.equal("jimin");
    expect(innerFn()).to.equal(178); // const innerFn = outerFn(); 저장이 되었기 때문에 실행 가능.
  });
});


⚙️ ArrowFunction.


describe("화살표 함수에 관해서", function () {
  it("함수 표현식 사용법을 복습합니다", function () {
    const add = function (x, y) {
      return x + y;
    };

    expect(add(5, 8)).to.eql(13);
  });

  it("화살표 함수 사용법을 익힙니다", function () {
    const add = (x, y) => {
      return x + y;
    };
    expect(add(10, 20)).to.eql(30);

    // 리턴을 생략
    const subtract = (x, y) => x - y;
    expect(subtract(10, 20)).to.eql(-10);

    // 소괄호 가능
    const multiply = (x, y) => (x * y);
    expect(multiply(10, 20)).to.eql(200);

    // 파라미터가 하나일 경우 소괄호 생략이 가능
    const divideBy10 = (x) => x / 10;
    expect(divideBy10(100)).to.eql(10);
  });

  it("화살표 함수를 이용해 클로저를 표현합니다", function () {
    const adder = (x) => {
      return (y) => {
        return x + y;
      };
    };
	
    // adder(50) 함수를 실행시킨 결과(return된 함수)를 매개변수 10을 넣어서 실행시킨다.
    expect(adder(50)(10)).to.eql(60);

    const subtractor = (x) => (y) => x - y;

    // const subtractor = function (x) {
    //   function a(y) {
    //     return x - y;
    //   }
    //   return a;
    // };

    // const asdg = subtractor(50)
    // let last = asdg(10)

    // last = subtractor(50)(10)

    // expect(last).to.eql(40);

    expect(subtractor(50)(10)).to.eql(40); // subtractor(50) 함수를 실행시킨 결과에 매개변수 10을 넣어서 실행.
    									   // return되는 값은 x-y를 거친 50-10 = 10이다.

    const htmlMaker = (tag) => (textContent) =>
      `<${tag}>${textContent}</${tag}>`;
    expect(htmlMaker("div")("code states")).to.eql(`<div>code states</div>`);

    // liMaker 변수에 매개변수 "li"를 갖는 htmlMaker를 실행해서 리턴된 값을 저장한다.
    // 형태 꼬릿말 참고
    const liMaker = htmlMaker("li");
    expect(liMaker("1st item")).to.eql(`<li>1st item</li>`); // 매개변수 "1st item" 을 넣어주고 리턴 값을 받는다.
    expect(liMaker("2nd item")).to.eql(`<li>2nd item</li>`);
  });
});

// 함수 표현식

// liMaker = function (textContent){
//   return `<li>${textContent}</li>`;
// }
profile
아이디어가 넘치는 프론트엔드를 꿈꿉니다 🔥

0개의 댓글