Unit9 - [JavaScript] 핵심 개념과 주요 문법 - 3

강성일·2023년 5월 1일
0
post-thumbnail

⚙️ Types-part2.


describe("primitive data type과 reference data type에 대해서 학습합니다.", function () {
 
  it("원시 자료형은 값 자체에 대한 변경이 불가능(immutable)합니다.", function () {
    let name = "codestates";
    expect(name).to.equal("codestates");
    expect(name.toUpperCase()).to.equal("CODESTATES");
    expect(name).to.equal("codestates");
    // 새로운 값으로 재할당은 가능
    name = name.toUpperCase();
    expect(name).to.equal("CODESTATES");

  it("원시 자료형을 변수에 할당할 경우, 값 자체의 복사가 일어납니다.", function () {
    let overTwenty = true;
    let allowedToDrink = overTwenty;

    overTwenty = false;
    expect(overTwenty).to.equal(false);
    expect(allowedToDrink).to.equal(true);

    let variable = "variable";
    let variableCopy = "variableCopy";
    variableCopy = variable;
    variable = variableCopy;
    expect(variable).to.equal("variable");
  });

  it("원시 자료형 또는 원시 자료형의 데이터를 함수의 전달인자로 전달할 경우, 값 자체의 복사가 일어납니다.", function () {
    let currentYear = 2020;
    function afterTenYears(year) {
      year = year + 10;
    }
    afterTenYears(currentYear);
    expect(currentYear).to.equal(2020);
    function afterTenYears2(currentYear) {
      currentYear = currentYear + 10;
      return currentYear;
    }
    let after10 = afterTenYears2(currentYear);
    expect(currentYear).to.equal(2020);
    expect(after10).to.equal(2030);
    
  it("참조 자료형의 데이터는 동적(dynamic)으로 변합니다.", function () {
    const arr = [1, 2, 3];
    expect(arr.length).to.equal(3);
    arr.push(4, 5, 6);
    expect(arr.length).to.equal(6);
    arr.pop();
    expect(arr.length).to.equal(5);

    const obj = {};
    expect(Object.keys(obj).length).to.equal(0);
    obj["name"] = "codestates";
    obj.quality = "best";
    obj.product = [
      "sw engineering",
      "product manager",
      "growth marketing",
      "data science",
    ];
    expect(Object.keys(obj).length).to.equal(3);
    delete obj.name;
    expect(Object.keys(obj).length).to.equal(2);
  });

  it("참조 자료형을 변수에 할당할 경우, 데이터의 주소가 저장됩니다.", function () {
    const overTwenty = ["hongsik", "minchul", "hoyong"];
    let allowedToDrink = overTwenty;

    overTwenty.push("san");
    expect(allowedToDrink).to.deep.equal([
      "hongsik",
      "minchul",
      "hoyong",
      "san",
    ]);
    overTwenty[1] = "chanyoung";
    expect(allowedToDrink[1]).to.deep.equal("chanyoung");

    const ages = [22, 23, 27];
    allowedToDrink = ages;
    expect(allowedToDrink === ages).to.equal(true);
    expect(allowedToDrink === [22, 23, 27]).to.equal(false);

    const nums1 = [1, 2, 3];
    const nums2 = [1, 2, 3];
    expect(nums1 === nums2).to.equal(false);

    const person = {
      hi: "hi",
      son: {
        age: 9,
      },
    };

    const boy = person.son;
    boy.age = 20;

    expect(person.son.age).to.equal(20);
    expect(person.son === boy).to.equal(true);
    expect(person.son === { age: 9 }).to.equal(false);
    expect(person.son === { age: 20 }).to.equal(false);
  });
});


⚙️ Arrow.


describe("Array에 대해서 학습합니다.", function () {
  it("Array의 기본을 확인합니다.", function () {
    const emptyArr = [];
    expect(typeof emptyArr === "array").to.equal(false);
    expect(emptyArr.length).to.equal(0);

    const multiTypeArr = [
      0,
      1,
      "two",
      function () {
        return 3;
      },
      { value1: 4, value2: 5 },
      [6, 7],
    ];
    expect(multiTypeArr.length).to.equal(6);
    expect(multiTypeArr[0]).to.equal(0);
    expect(multiTypeArr[2]).to.equal("two");
    expect(multiTypeArr[3]()).to.equal(3);
    expect(multiTypeArr[4].value1).to.equal(4);
    expect(multiTypeArr[4].value2).to.equal(5);
    expect(multiTypeArr[5][1]).to.equal(7);
  });

  it("Array의 요소(element)를 다루는 방법을 확인합니다.", function () {
    const arr = [];
    expect(arr).to.deep.equal([]);

    arr[0] = 1;
    expect(arr).to.deep.equal([1]);

    arr[1] = 2;
    expect(arr).to.deep.equal([1, 2]);

    arr.push(3);
    expect(arr).to.deep.equal([1, 2, 3]);

    const poppedValue = arr.pop();
    expect(poppedValue).to.equal(3);
    expect(arr).to.deep.equal([1, 2]);
  });

  it("Array 메소드 slice를 확인합니다.", function () {
    const arr = ["peanut", "butter", "and", "jelly"];

    expect(arr.slice(1)).to.deep.equal(["butter", "and", "jelly"]);
    expect(arr.slice(0, 1)).to.deep.equal(["peanut"]);
    expect(arr.slice(0, 2)).to.deep.equal(["peanut", "butter"]);
    expect(arr.slice(2, 2)).to.deep.equal([]);
    expect(arr.slice(2, 20)).to.deep.equal(["and", "jelly"]);
    expect(arr.slice(3, 0)).to.deep.equal([]);
    expect(arr.slice(3, 100)).to.deep.equal(["jelly"]);
    expect(arr.slice(5, 1)).to.deep.equal([]);

    // arr.slice는 arr의 값을 복사하여 새로운 배열을 리턴
    expect(arr.slice(0)).to.deep.equal(["peanut", "butter", "and", "jelly"]);
  });

  it("Array를 함수의 전달인자로 전달할 경우, reference가 전달됩니다.", function () {
    
    const arr = ["zero", "one", "two", "three", "four", "five"];

    function passedByReference(refArr) {
      refArr[1] = "changed in function";
    }
    passedByReference(arr);
    expect(arr[1]).to.equal("changed in function");

    const assignedArr = arr;
    assignedArr[5] = "changed in assignedArr";
    expect(arr[5]).to.equal("changed in assignedArr");

    const copiedArr = arr.slice();
    copiedArr[3] = "changed in copiedArr";
    expect(arr[3]).to.equal("three");
  });

  it("Array 메소드 shift와 unshift를 확인합니다.", function () {
    const arr = [1, 2];

    arr.unshift(3);
    expect(arr).to.deep.equal([3, 1, 2]);

    const shiftedValue = arr.shift();
    expect(shiftedValue).to.deep.equal(3);
    expect(arr).to.deep.equal([1, 2]);
  });
});


⚙️ Object.


describe("Object에 대해서 학습합니다.", function () {
  
  it("Object의 기본을 확인합니다.", function () {
    const emptyObj = {};
    expect(typeof emptyObj === "object").to.equal(true);
    expect(emptyObj.length).to.equal(undefined);

    const megalomaniac = {
      mastermind: "Joker",
      henchwoman: "Harley",
      getMembers: function () {
        return [this.mastermind, this.henchwoman];
      },
      relations: ["Anarky", "Duela Dent", "Lucy"],
      twins: {
        "Jared Leto": "Suicide Squad",
        "Joaquin Phoenix": "Joker",
        "Heath Ledger": "The Dark Knight",
        "Jack Nicholson": "Tim Burton Batman",
      },
    };

    expect(megalomaniac.length).to.equal(undefined);
    expect(megalomaniac.mastermind).to.equal("Joker");
    expect(megalomaniac.henchwoman).to.equal("Harley");
    expect(megalomaniac.henchWoman).to.equal(undefined);
    expect(megalomaniac.getMembers()).to.deep.equal(["Joker", "Harley"]);
    expect(megalomaniac.relations[2]).to.equal("Lucy");
    expect(megalomaniac.twins["Heath Ledger"]).to.deep.equal("The Dark Knight");
  });

  it("Object의 속성(property)를 다루는 방법을 확인합니다.", function () {
    const megalomaniac = { mastermind: "Agent Smith", henchman: "Agent Smith" };

    expect("mastermind" in megalomaniac).to.equal(true);

    megalomaniac.mastermind = "Neo";
    expect(megalomaniac["mastermind"]).to.equal("Neo");

    expect("secretary" in megalomaniac).to.equal(false);

    megalomaniac.secretary = "Agent Smith";
    expect("secretary" in megalomaniac).to.equal(true);

    delete megalomaniac.henchman;
    expect("henchman" in megalomaniac).to.equal(false);
  });

  it("'this'는 method를 호출하는 시점에 결정됩니다.", function () {
    const currentYear = new Date().getFullYear();
    const megalomaniac = {
      mastermind: "James Wood",
      henchman: "Adam West",
      birthYear: 1970,
      calculateAge: function (currentYear) {
        return currentYear - this.birthYear;
      },
      changeBirthYear: function (newYear) {
        this.birthYear = newYear;
      },
    };

    expect(currentYear).to.equal(2023);
    expect(megalomaniac.calculateAge(currentYear)).to.equal(53);

    megalomaniac.birthYear = 2000;
    expect(megalomaniac.calculateAge(currentYear)).to.equal(23);

    megalomaniac.changeBirthYear(2010);
    expect(megalomaniac.calculateAge(currentYear)).to.equal(13);
  });

  it("객체의 method를 정의하는 방법을 확인합니다.", function () {
    const megalomaniac = {
      mastermind: "Brain",
      henchman: "Pinky",
      getFusion: function () {
        return this.henchman + this.mastermind;
      },
      battleCry(numOfBrains) {
        return (
          `They are ${this.henchman} and the` +
          ` ${this.mastermind}`.repeat(numOfBrains)
        );
      },
    };

    expect(megalomaniac.getFusion()).to.deep.equal("PinkyBrain");
    expect(megalomaniac.battleCry(3)).to.deep.equal(
      `They are Pinky and the Brain Brain Brain`
    );
  });

  it("Object를 함수의 전달인자로 전달할 경우, reference가 전달됩니다.", function () {
    const obj = {
      mastermind: "Joker",
      henchwoman: "Harley",
      relations: ["Anarky", "Duela Dent", "Lucy"],
      twins: {
        "Jared Leto": "Suicide Squad",
        "Joaquin Phoenix": "Joker",
        "Heath Ledger": "The Dark Knight",
        "Jack Nicholson": "Tim Burton Batman",
      },
    };

    function passedByReference(refObj) {
      refObj.henchwoman = "Adam West";
    }
    passedByReference(obj);
    expect(obj.henchwoman).to.equal("Adam West");

    const assignedObj = obj;
    assignedObj["relations"] = [1, 2, 3];
    expect(obj["relations"]).to.deep.equal([1, 2, 3]);

    const copiedObj = Object.assign({}, obj);

    copiedObj.mastermind = "James Wood";
    expect(obj.mastermind).to.equal("Joker");

    obj.henchwoman = "Harley";
    expect(copiedObj.henchwoman).to.equal("Adam West");

    delete obj.twins["Jared Leto"];
    expect("Jared Leto" in copiedObj.twins).to.equal(false); // 얕은 복사
    // 값 들(원시 자료형)은 서로 영향을 안 줌!
    // But. 객체나 배열(참조 자료형) 안에 값을 조작하는 것은 영향을 미침
  });
});


⚙️ SpreadSyntax.


describe("Spread syntax에 대해 학습합니다.", function () {
  it("전개 문법(spread syntax)을 학습합니다.", function () {
    const spread = [1, 2, 3];
    const arr = [0, ...spread, 4];
    expect(arr).to.deep.equal([0, 1, 2, 3, 4]);
  });

  it("빈 배열에 전개 문법을 사용할 경우, 아무것도 전달되지 않습니다.", function () {
    const spread = [];
    const arr = [0, ...spread, 1];
    expect(arr).to.deep.equal([0, 1]);
  });

  it("여러 개의 배열을 이어붙일 수 있습니다.", function () {
    const arr1 = [0, 1, 2];
    const arr2 = [3, 4, 5];
    const concatenated = [...arr1, ...arr2];
    expect(concatenated).to.deep.equal([0, 1, 2, 3, 4, 5]);
    // 아래 코드도 같은 동작을 수행한다.
    //  arr1.concat(arr2);
  });

  it("여러 개의 객체를 병합할 수 있습니다.", function () {
    const fullPre = {
      cohort: 7,
      duration: 4,
      mentor: "hongsik",
    };

    const me = {
      time: "0156",
      status: "sleepy",
      todos: ["coplit", "koans"],
    };

    const merged = { ...fullPre, ...me };

    expect(merged).to.deep.equal({
      cohort: 7,
      duration: 4,
      mentor: "hongsik",
      time: "0156",
      status: "sleepy",
      todos: ["coplit", "koans"],
    });
  });

  it("Rest Parameter는 함수의 전달인자를 배열로 다룰 수 있게 합니다.", function () {
    
    function returnFirstArg(firstArg) {
      return firstArg;
    }
    expect(returnFirstArg("first", "second", "third")).to.equal("first");

    function returnSecondArg(firstArg, secondArg) {
      return secondArg;
    }
    expect(returnSecondArg("only give first arg")).to.equal(undefined);

    function getAllParamsByRestParameter(...args) {
      return args;
    }

    function getAllParamsByArgumentsObj() {
      return arguments;
    }

    const restParams = getAllParamsByRestParameter("first", "second", "third");
    const argumentsObj = getAllParamsByArgumentsObj("first", "second", "third");

    expect(restParams).to.deep.equal(["first", "second", "third"]);
    expect(Object.keys(argumentsObj)).to.deep.equal(["0", "1", "2"]);
    expect(Object.values(argumentsObj)).to.deep.equal([
      "first",
      "second",
      "third",
    ]);

    expect(restParams === argumentsObj).to.deep.equal(false);
    expect(typeof restParams).to.deep.equal("object");
    expect(typeof argumentsObj).to.deep.equal("object");
    expect(Array.isArray(restParams)).to.deep.equal(true);
    expect(Array.isArray(argumentsObj)).to.deep.equal(false);

    const argsArr = Array.from(argumentsObj);
    expect(Array.isArray(argsArr)).to.deep.equal(true);
    expect(argsArr).to.deep.equal(["first", "second", "third"]);
    expect(argsArr === restParams).to.deep.equal(false);
  });

  it("Rest Parameter는 전달인자의 수가 정해져 있지 않은 경우에도 유용하게 사용할 수 있습니다.", function () {
    function sum(...nums) {
      let sum = 0;
      for (let i = 0; i < nums.length; i++) {
        sum = sum + nums[i];
      }
      return sum;
    }
    expect(sum(1, 2, 3)).to.equal(6);
    expect(sum(1, 2, 3, 4)).to.equal(10);
  });

  it("Rest Parameter는 전달인자의 일부에만 적용할 수도 있습니다.", function () {
    function getAllParams(required1, required2, ...args) {
      return [required1, required2, args];
    }
    expect(getAllParams(123)).to.deep.equal([123, undefined, []]);

    function makePizza(dough, name, ...toppings) {
      const order = `You ordered ${name} pizza with ${dough} dough and ${toppings.length} extra toppings!`;
      return order;
    }
    expect(makePizza("original")).to.equal(
      `You ordered undefined pizza with original dough and 0 extra toppings!`
    );
    expect(makePizza("thin", "pepperoni")).to.equal(
      `You ordered pepperoni pizza with thin dough and 0 extra toppings!`
    );
    expect(
      makePizza("napoli", "meat", "extra cheese", "onion", "bacon")
    ).to.equal(
      `You ordered meat pizza with napoli dough and 3 extra toppings!`
    );
  });
});


⚙️ Destructuring.


describe("구조 분해 할당(Destructuring Assignment)에 관해서", () => {
  it("배열을 분해합니다", () => {
    const array = ["code", "states", "im", "course"];

    const [first, second] = array;
    expect(first).to.eql("code");
    expect(second).to.eql("states");

    const result = [];
    function foo([first, second]) {
      result.push(second);
      result.push(first);
    }

    foo(array);
    expect(result).to.eql(["states", "code"]);
  });

  it("rest/spread 문법을 배열 분해에 적용할 수 있습니다", () => {
    const array = ["code", "states", "im", "course"];
    const [start, ...rest] = array;
    expect(start).to.eql("code");
    expect(rest).to.eql(["states", "im", "course"]);

    // 다음과 같은 문법은 사용할 수 없다.
    // 할당하기 전 왼쪽에는, rest 문법 이후에 쉼표가 올 수 없다.
    // const [first, ...middle, last] = array
  });

  it("객체의 단축(shorthand) 문법을 익힙니다", () => {
    const name = "김코딩";
    const age = 28;

    const person = {
      name,
      age,
      level: "Junior",
    };
    expect(person).to.eql({
      name: "김코딩",
      age: 28,
      level: "Junior",
    });
  });

  it("객체를 분해합니다", () => {
    const student = { name: "박해커", major: "물리학과" };

    const { name } = student;
    expect(name).to.eql("박해커");
  });

  it("rest/spread 문법을 객체 분해에 적용할 수 있습니다 #1", () => {
    const student = { name: "최초보", major: "물리학과" };
    const { name, ...args } = student;

    expect(name).to.eql("최초보");
    expect(args).to.eql({ major: "물리학과" });
  });

  it("rest/spread 문법을 객체 분해에 적용할 수 있습니다 #2", () => {
    const student = {
      name: "최초보",
      major: "물리학과",
      lesson: "양자역학",
      grade: "B+",
    };

    function getSummary({ name, lesson: course, grade }) {
      return `${name}님은 ${grade}의 성적으로 ${course}을 수강했습니다`;
    }

    expect(getSummary(student)).to.eql(
      `최초보님은 B+의 성적으로 양자역학을 수강했습니다`
    );
  });

  it("rest/spread 문법을 객체 분해에 적용할 수 있습니다 #3", () => {
    const user = {
      name: "김코딩",
      company: {
        name: "Code States",
        department: "Development",
        role: {
          name: "Software Engineer",
        },
      },
      age: 35,
    };

    const changedUser = {
      ...user,
      name: "박해커",
      age: 20,
    };

    const overwriteChanges = {
      name: "박해커",
      age: 20,
      ...user,
    };

    const changedDepartment = {
      ...user,
      company: {
        ...user.company,
        department: "Marketing",
      },
    };

    expect(changedUser).to.eql({
      name: "박해커",
      company: {
        name: "Code States",
        department: "Development",
        role: {
          name: "Software Engineer",
        },
      },
      age: 20,
    });

    expect(overwriteChanges).to.eql({
      name: "김코딩",
      company: {
        name: "Code States",
        department: "Development",
        role: {
          name: "Software Engineer",
        },
      },
      age: 35,
    });

    expect(changedDepartment).to.eql({
      name: "김코딩",
      company: {
        name: "Code States",
        department: "Marketing",
        role: {
          name: "Software Engineer",
        },
      },
      age: 35,
    });
  });
});
profile
아이디어가 넘치는 프론트엔드를 꿈꿉니다 🔥

0개의 댓글