JavaScript & TypeScript

[JS] 복습(과제) 정리

반응형

1. typeOf 특징

(!(false)) === true // !(값) 을 사용하여 반대값을 출력할 수 있습니다.

let actualValue = (1 + 1).toString();
expect(actualValue).to.equal('2'); // 보이는 값이 같을지라도 타입이 다르면 다른 값 입니다.

2. typeOf 특징

let actualValue = 1 + 1;
    let expectedValue = 2;
    expect(actualValue === expectedValue).to.be.true; // 넘버 타입은 연산을 하고

    expect(1 + '1').to.equal('11'); // 스트링 타입은 이어 붙이기를 합니다.

3. 배열의 특징

 //배열
 const arr = [];
 const toBePushed = 42;
 
 arr.push(toBePushed); 
 // arr === [42] (이해를 돕기 위해 표현 했습니다. 결과 값은 false가 나옵니다.)
 // arr과 [42] (배열과 객체)는 생성된 곳이 다르면 같다고 표현하지 않습니다.
 
 const로 선언된 배열의 경우 새로운 요소를 추가하거나 삭제 할 수 있습니다.
 재할당은 금지.
 
 //객체
const obj = { x: 1 };

delete obj.x;
obj.x.===undefined

 

4. 함수 선언식

//function 키워드를 생략하고 화살표 => 를 붙입니다
const add = (x, y) => {
  return x + y
}


// 리턴을 생략할 수 있습니다
const subtract = (x, y) => x - y


// 필요에 따라 소괄호를 붙일 수도 있습니다
const multiply = (x, y) => (x * y)


// 파라미터가 하나일 경우 소괄호 생략이 가능합니다
const divideBy10 = x => x / 10


  //화살표 함수를 이용해 클로저를 표현합니다 
function () {
  const adder = x => {
    return y => {
    return x + y
  }

5. 스코프 , 클로저

함수 typeOf 사용했을때에 'function' 출력


//스코프

it(function () {
    let message = 'Outer';

    function getMessage() {
      return message;
    }

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

    expect(getMessage()).to.equal('Outer'); 
    expect(shadowGlobal()).to.equal('Inner');
    expect(message).to.equal('Outer'); // 변수 선언이 함수의 밖이냐 안이냐에 따라 다르다.
  });
  
  
  // 클로저
  
    it( function () {
    function increaseBy(increaseByAmount) {
      return function (numberToIncrease) {
        return numberToIncrease + increaseByAmount;
      };
    }

    const increaseBy3 = increaseBy(3);  // 함수안에 함수를 넣듯이 변수안에 변수를 넣어서 초기값 3
    const increaseBy5 = increaseBy(5);	// 5를 고정시킨다.

    expect(increaseBy3(10)).to.equal(13);
    expect(increaseBy5(10)).to.equal(15);
    expect(increaseBy(8)(6) + increaseBy(5)(9)).to.equal(28);
	// 또는 변수 선언을 따로 하지 않고 ()()를 사용하여 순서대로 넣는다.

 

6.

자바스크립트에서 원시 자료형(primitive data type 또는 원시값)은 객체가 아니면서 method를 가지지 않는 아래 6가지의 데이터를 말합니다. string, number, bigint, boolean, undefined, symbol, (null)

원시 자료형은 값 자체에 대한 변경이 불가능 합니다. 

it(fuction (){
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);
    })

원시 자료형 또는 원시 자료형의 데이터를 함수의 인자로 전달할 경우, 값 자체의 복사가 일어납니다.

함수에 변수 생성이 가능하다는 표현이고 아래와 같이 표현 할 수 있다.

function 함수이름 (함수변수)

 

 

바스크립트에서 원시 자료형이 아닌 모든 것은 참조 자료형 입니다. 배열([])과 객체({}), 함수(function(){})가 대표적 입니다.

'참조 자료형의 데이터는 동적(dynamic)으로 변합니다. length 매서드 사용 가능.

 

참조 자료형을 변수에 할당할 경우, 데이터의 주소가 저장됩니다.

참조 자료형의 경우, 값 자체의 복사가 일어나지 않는 이유는 어느 정도 납득할만한 이유가 있습니다.

배열이 얼마나 많은 데이터를 가지고 있는지가 프로그램의 실행 중 수시로 변경될 수 있기 때문입니다.

쉽게 생각해서 number 타입 데이터 100만개를 요소로 갖는 배열을 생각해 봅시다.

따로 명시하지 않는이상 100만개의 데이터를 일일히 복사하는 것은 상당히 비효율적입니다.

따라서 일단은 주소만 복사해서 동일한 데이터를 바라보는 게 만드는 것이 효율적입니다.

(to.equal 보다는 to deep.equal 을 선언해야 성립되는 이유

.deep.equal은 배열의 요소나 객체의 속성이 서로 같은지 확인하는 matcher)

it ( function(){
const person = {
    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);
})

 

const nums1 = [1, 2, 3];

const nums2 = [1, 2, 3];

expect(nums1 === nums2).to.equal(false);

배열 nums1과 배열 num2에는 동일한 데이터 [1, 2, 3]이 들어있는 게 분명해 보이는데, 이 둘은 같지가 않습니다.

사실 변수 num1와 num2는 배열이 아닙니다. 참조 타입의 변수에는 (데이터에 대한) 주소만이 저장된다는 것을 떠올려 봅시다.

 

정확히 말해서 변수 num1은 데이터 [1, 2, 3]이 저장되어 있는 메모리 공간(heap)을 가리키는 주소를 담고 있습니다.

따라서 위의 코드는 각각 다음의 의미를 가지고 있습니다.

const nums1 = [1, 2, 3]; // [1, 2, 3]이 heap에 저장되고, 이 위치의 주소가 변수 num1에 저장된다.

const nums2 = [1, 2, 3]; // [1, 2, 3]이 heap에 저장되고, 이 위치의 주소가 변수 num2에 저장된다.

이제 heap에는 두 개의 [1, 2, 3]이 저장되어 있고, 각각에 대한 주소가 변수 num1, num2에 저장되어 있습니다.

이게 비효율적으로 보일수도 있습니다. 굳이 같은 데이터를 왜 한번 더 저장하는 지 이해하기란 쉽지 않습니다.

 

하지만 [1, 2, 3]이 아니라 상당히 큰 데이터(예. length가 100,000인 배열)를 가지고 다시 생각해 봅시다.

const nums1 = [10, 2, 71, ..., 987]; // 길이 100,000개인 배열

const nums2 = [10, 2, 71, ..., 987]; // 길이 100,000개인 배열

이 두 배열이 서로 같아서 두 번 저장할 필요가 없다고 말하려면, 일단 두 배열이 같은지 확인해야 합니다.

이런 작업을 Object 자료형을 쓸 때마다 한다고 가정해보면, 이것이 얼마나 비효율적인지를 금방 알 수 있습니다.

 

 

7. Array

배열 매소드
const arr = [1, 2, 3]
arr.pop();  맨뒤 빼기
arr.push(4); 맨뒤 넣기
arr.slice(0, n); 0이상 n미만의 값을 제거한 새로운 배열(또는 객체)
arr.shift(); 맨앞 빼기
arr.unshift(0); 맨앞 값 넣기
Array.isArray(arr) 배열인지 여부

8. 객체 생략.

Object.assign({}, obj); 을 통한 복사는 reference variable은 주소만 복사

 

9. Spread, rest

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

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

    const merged = { ...fullPre, ...me};
    // 변수 'merged'에 할당된 것은 'obj1'과 'obj2'의 value일까요, reference일까요?
    // 만약 값(value, 데이터)이 복사된 것이라면, shallow copy일까요, deep copy일까요?

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

 

 

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 () {

    // rest parameter는 항상 배열입니다.
    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!');
  });

 

반응형

'JavaScript & TypeScript' 카테고리의 다른 글

[JS] 고차함수  (1) 2021.06.06
[JS] DOM  (6) 2021.06.06
[JS] Spread, Rest, Destructing  (2) 2021.05.31
[JS] 스코프, 클로저  (0) 2021.05.29
[JS] 객체  (1) 2021.05.27