본문 바로가기
TIL

2024.02.28 7일차 JavaScript

by Song.dev 2024. 2. 28.

과제 풀면서 헷갈렸거나 몰랐던 부분들 정리

 

매개변수로 num = 5

  * 인자로 아무것도 없을 경우 num = 5가 적용되어 5를 반환

       매개변수가 없을 경우 undefined가 아닌 디폴트 값을 사용하도록 설정할 수 있음

  * 인자로 10을 넣을 경우 num에 5 대신 10이 적용되어 10을 반환 

function defaultParameter(num = 5) {
 // console.log(num)
 // if(num === undefined) num = 5; 와 매개변수 num = 5 같은 코드
  return num;
}

defaultParameter(10); // 10 콘솔로 확인한 num = 10
defaultParameter(); // 5 콘솔로 확인한 num = 5

 

화살표 함수의 클로저

    const adder = x => {
      return y => {      // y 매개변수 1개
        return x + y
      }
    }

    console.log(adder(50)(10)) // 60

    const subtractor = x => y => {   // {return y => { return  }} 바깥 {} 생략
      return x - y
    }
    // const subtractor = x => y => x - y     // 완전히 생략한 형태
	
    console.log(adder(50)(10)) // 40

 

 

빈 배열, 빈 객체의 자료형과 length

  * 빈 배열 : type은 object, length 0      (Array.isArray() 사용해야 배열인지 확인 가능)

  * 빈 객체 : type은  object, length undefined 

                   Object.keys(obj).length  : object 요소의 개수를 구하는 법

                   또는 for...in으로 key를 순회할 때마다 count++로 구할 수 있음

const emptyArr = [];
console.log(typeof emptyArr === 'array');  // false
console.log(typeof emptyArr);  // object
console.log(emptyArr.length);  // 0


const emptyObject = {};
typeof emptyObject; // object 
emptyObject.length; // undefined
emptyArr.length; // 0

 

arr.slice([begin[, end]]) 메서드

  * 깊은 복사 (원본과 다른 주소를 갖는 배열을 반환)

  * begin >= end 인 경우 빈 배열을 반환

  * end >= arr.length 인 경우 begin부터 배열의 마지막까지 포함하는 배열을 반환

// slice
const arr = ['cat', 'dog', 'and', 'hamster'];
arr.slice(2, 2); // []
arr.slice(5, 1); // []
arr.slice(2, 20); // ['and', 'hamster'] begin부터 배열의 끝까지

 

원본 배열에서 요소의 얕은 복사본을 반환

객체 참조(및 실제 객체가 아님)의 경우, slice()는 객체 참조를 새 배열로 복사합니다.

원본 배열과 새 배열은 모두 동일한 객체를 참조합니다.

참조 된 객체가 변경되면 변경 내용은 새 배열과 원래 배열 모두에서 볼 수 있습니다.

 

* .repeat(num) : num 횟수만큼 앞의 문자를 반복함

    ex) "abc".repeat(3); // "abcabcabc"

 

 

Object.assign() 메서드

* 원시형 타입은 값 자체가 복사 되지만 1depth는 깊은 복사,  2depth 이상은 얕은 복사

             → 깊은 복사만 할 수 있는 방식으로 통일해서 사용해야 함! (JSON, 라이브러리)

    다차원 객체, 배열은 깊은 복사가 안 되기 때문에

    다차원 속성들은 얕은 복사 (원본, 복사본의 변화가 서로 영향을 끼침) 

         ex) obj.twins 는 얕은 복사가 되어 delete obj.twins['Jared Leto'] 영향을 받아 copiedObj에서도 삭제됨 

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',
  },
};

const copiedObj = Object.assign({}, obj);
copiedObj.mastermind = 'James Wood';   
delete obj.twins['Jared Leto'];
expect('Jared Leto' in copiedObj.twins).to.equal(false);

 

* 'property' in Object  : true / false 반환

* 깊은 복사 주의점

   Object.assign()은 속성의 값을 복사하기 때문에, 깊은 복사를 수행하려면 다른 방법을 사용
   만약 출처 값이 객체에 대한 참조라면 참조 값만 복사

 

spread 문법

    const arr1 = [0, 1, 2];
    const arr2 = [3, 4, 5];
    const concatenated = [...arr1, ...arr2]; // [...arr1, ...arr2, ...arr2] 여러 개 사용 가능
    
    expect(concatenated).to.deep.equal([0, 1, 2, 3, 4, 5]);
    
    
    const merged = { ...fullPre, ...me }; // 두 객체의 속성(키)가 같다면 나중의 속성이 할당하는 값으로 바뀜

 

* 매개변수가 1개인 함수에 여러 인자를 넣으면 첫번째 인자만 함수에 전달되고 오류 발생하지 않음

* 매개변수가 2개인 함수에 하나의 인자를 넣으면 두번째 매개변수는 undefined

 

arguments 객체

arguments 객체는 함수에 전달된 인수에 해당하는 Array 형태의 객체

참고: "Array 형태"란 arguments가 length 속성과 더불어 0부터 인덱스 된 다른 속성을 가지고 있지만, 

          Array의 forEach, map과 같은 내장 메서드를 가지고 있지 않다는 뜻 (출처 MDN)

    // arguments를 통해 '비슷하게' 함수의 전달인자들을 다룰 수 있음 (spread syntax 도입 이전)
    // arguments는 모든 함수의 실행 시 자동으로 생성되는 '객체'
    
    function getAllParamsByRestParameter(...args) { // 여러 인자가 들어왔을 때 풀어주지 않고 
      return args;         // rest문법에 따라 하나의 배열로 리턴
    }                      // ...args에 배열을 넣으면 [...args], 즉 배열 안의 배열이고 길이는 1
    // let arr = [1, 2, 3, 4];
    // gA(...arr); // 배열을 풀어서 배열에 넣음 [1, 2, 3, 4]

    function getAllParamsByArgumentsObj() {
      return arguments;
    }
	
    // ['first', 'second', 'third']
    const restParams = getAllParamsByRestParameter('first', 'second', 'third');
    //{'0': 'first, '1': 'second', '2': 'third'}
    const argumentsObj = getAllParamsByArgumentsObj('first', 'second', 'third');

    console.log(restParams); // ['first', 'second', 'third']
    console.log(Object.keys(argumentsObj); // ['0', '1', '2']);
    console.log(Object.values(argumentsObj); // ['first', 'second', 'third']
    
    // arguments와 rest parameter를 통해 배열로 된 전달인자(args)의 차이를 확인하시기 바랍니다.
    console.log(restParams === argumentsObj); // false
    console.log(typeof restParams); // 'object'
    console.log(typeof argumentsObj); // 'object'

    console.log(Array.isArray(restParams); // true
    console.log(Array.isArray(argumentsObj); // false

restParams.0 // error

restParams['0'] // 'first'

 

 

Array.from()

Array.from() 정적 메서드는 순회 가능 또는 유사 배열 객체에서

얕게 복사된 새로운 Array 인스턴스를 생성 및 반환 (출처 MDN)

객체  →  배열 (key 제외하고 value만 요소로 들어옴)

console.log(Array.from('foo'));
// Expected output: Array ["f", "o", "o"]

console.log(Array.from([1, 2, 3], (x) => x + x));
// Expected output: Array [2, 4, 6]

const argsArr = Array.from(argumentsObj);  // 새로운 배열을 생성
console.log(Array.isArray(argsArr); // true;
console.log(argsArr); // ['first', 'second', 'third']
console.log(argsArr === restParams) // false

 

 

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/from

 

Array.from() - JavaScript | MDN

Array.from() 정적 메서드는 순회 가능 또는 유사 배열 객체에서 얕게 복사된 새로운 Array 인스턴스를 생성합니다.

developer.mozilla.org

 

 

rest 문법에서 인자가 부족할 경우

고정값은 undefined, 나머지는 [] 빈 배열

  * 인자가 많은 경우 [1, 2, [3, 4, 5]] 형식으로 들어오게 됨 ( ...args = [3, 4, 5])

    function getAllParams(required1, required2, ...args) {
      return [required1, required2, args];
    }
    expect(getAllParams(123)).to.deep.equal([123, undefined, []]);

 

구조 분해

구조 분해 destructuring

배열의 첫번째 요소를 first, 두번째 요소를 second

    const array = ['java', 'spring', 'im', 'course']

    const [first, second] = array
    console.log(first);  // 'java'
    console.log(second);  // 'spring'
    
    
    const [0, 1] = array;
    console.log(0);
    console.log(1);
    // Uncaught SyntaxError: Invalid destructuring assignment target
    
    const ['0', '1'] = array;
    // Uncaught SyntaxError: Invalid destructuring assignment target
   
   // rest/spread 문법을 배열 분해에 적용
    const [f, s] = array;
    console.log(f); // java
    
    const array = ['java', 'spring', 'im', 'course']
    const [start, ...rest] = array
    expect(start).to.eql('java')
    expect(rest).to.eql(['spring', 'im', 'course'])  // rest 나머지 요소를 갖는 배열

 

객체의 분해

  // rest/spread 문법을 객체 분해에 적용할 수 있습니다 #1
    const student = { name: '최초보', major: '물리학과' }
    const { name, ...args } = student     // 객체 분해 cf.배열 -> 배열로

    expect(name).to.eql('최초보')
    expect(args).to.eql({major: '물리학과'}) // 객체 분해는 객체로