some 메소드

some 메소드는 배열 안에 콜백함수가 리턴하는 조건을 만족하는 요소가 1개 이상 있는지를 확인하는 메소드이다. 
배열을 반복하면서 모든 요소가 콜백함수가 리턴하는 조건을 만족하지 않는다면 false를 리턴하고, 배열을 반복하면서 콜백함수가 리턴하는 조건을 만족하는 요소가 등장한다면 바로 true를 리턴하고 반복을 종료한다.

const numbers = [1, 3, 5, 7, 9];

// some: 조건을 만족하는 요소가 1개 이상 있는지
const someReturn = numbers.some((element, index, array) => {
  console.log(index); // 콘솔에는 0, 1, 2, 3까지만 출력됨.
  return element > 5;
});

console.log(someReturn); 
//출력
0
1
2
3
true;

 

every 메소드

every 메소드는 배열 안에 콜백 함수가 리턴하는 조건을 만족하지 않는 요소가 1개 이상 있는지를 확인하는 메소드이다.
배열을 반복하면서 모든 요소가 콜백함수가 리턴하는 조건을 만족한다면 true를 리턴하고, 배열을 반복하면서 콜백함수가 리턴하는 조건을 만족하지 않는 요소가 등장한다면 바로 false를 리턴하고 반복을 종료한다.

const numbers = [1, 3, 5, 7, 9];

// every: 조건을 만족하지 않는 요소가 1개 이상 있는지
const everyReturn = numbers.every((element, index, array) => {
  console.log(index); // 콘솔에는 0까지만 출력됨.
  return element > 5;
});

console.log(everyReturn); 
//출력
0
false;

+ 메소드를 호출하는 배열이 빈 배열일 경우 콜백함수를 실행하지도 않고 바로 some은 false, every는 true를 리턴한다.

'코린이 개념잡기 > JavaScript' 카테고리의 다른 글

배열 메소드 Ⅴ (sort, reverse)  (0) 2024.12.19
배열 메소드 Ⅳ (reduce)  (0) 2024.12.19
배열 메소드 Ⅱ (filter, find)  (0) 2024.12.19
배열 메소드 Ⅰ (forEach, map)  (0) 2024.12.19
에러와 에러 객체  (1) 2024.12.18

filter 메소드

filter 메소드는 배열의 요소를 하나씩 살펴보면서 콜백함수가 리턴하는 조건과 일치하는 요소만 모아서 새로운 배열을 리턴하는 메소드이다. (이름 그대로 어떤 조건에 따라 필터링된 새로운 배열을 얻고자 할 때 활용할 수 있다.)

//filter
const devices = [
  {name: 'GalaxyNote', brand: 'Samsung'},
  {name: 'MacbookPro', brand: 'Apple'},
  {name: 'Gram', brand: 'LG'},
  {name: 'SurfacePro', brand: 'Microsoft'},
  {name: 'ZenBook', brand: 'Asus'},
  {name: 'MacbookAir', brand: 'Apple'},
];

//map메소드와 비슷해보인다, 아규먼트가 되는 콜백함수 구조도 비슷하다.
const apples = devices.filter((element, index, array) => {
  return element.brand === 'Apple';
});

console.log(apples); // (2) [{name: "MacbookPro", brand: "Apple"}, {name: "MacbookAir", brand: "Apple"}]

 

filter가 map과 다른점: 리턴문으로 어떤 값을 전달하는게 아니라 true 혹은 false로 평가되는 조건식을 리턴해준다.
그러면 이 메소드를 호출한 배열을 반복하면서 콜백함수가 리턴하는 조건식이 true가 되는 요소만 모아서 새로운 배열을 리턴해준다.

그런데, filter 메소드는 항상 리턴값이 배열이기 때문에 아래 코드처럼 name 프로퍼티 값이 고유한 값을 활용해서 하나만 있는 요소를 필터링하더라도 결국에는 하나의 요소를 가진 배열을 리턴해준다.

const devices = [
  {name: 'GalaxyNote', brand: 'Samsung'},
  {name: 'MacbookPro', brand: 'Apple'},
  {name: 'Gram', brand: 'LG'},
  {name: 'SurfacePro', brand: 'Microsoft'},
  {name: 'ZenBook', brand: 'Asus'},
  {name: 'MacbookAir', brand: 'Apple'},
];

const myLaptop = devices.filter((element, index, array) => {
  return element.name === 'Gram';
});

console.log(myLaptop);
//출력되는 값
[{...}]

//그래서 spread 구문을 이용해서 배열을 벗겨내는 작업을 해야한다.
console.log(...myLaptop);
//출력되는 값
{name: "Gram", brand: "LG"}

find 메소드

find 메소드는 filter 메소드와 비슷하게 동작하지만, 배열의 요소들을 반복하는 중에 콜백함수가 리턴하는 조건과 일치하는 가장 첫번째 요소를 리턴하고 반복을 종료하는 메소드이다.

const devices = [
  {name: 'GalaxyNote', brand: 'Samsung'},
  {name: 'MacbookPro', brand: 'Apple'},
  {name: 'Gram', brand: 'LG'},
  {name: 'SurfacePro', brand: 'Microsoft'},
  {name: 'ZenBook', brand: 'Asus'},
  {name: 'MacbookAir', brand: 'Apple'},
];

const myLaptop = devices.find((element, index, array) => {
  console.log(index); // 콘솔에는 0, 1, 2까지만 출력됨.
  return element.name === 'Gram';
});

console.log(myLaptop); // {name: "Gram", brand: "LG"}

 

filter 와 find의 차이점

  1. filter는 리턴값이 배열이고, find는 값이다.
  2. 같은 배열에서 메소드를 호출하더라도 반복하는 횟수의 차이가 있을 수 있다. (프로그램의 효율 측면에서 중요! find의 경우 조건을 만족하는 하나의 값만 찾기 때문에 그 값을 찾는 순간 반복이 종료된다.)
const devices = [
  {name: 'GalaxyNote', brand: 'Samsung'},
  {name: 'MacbookPro', brand: 'Apple'},
  {name: 'Gram', brand: 'LG'},
  {name: 'SurfacePro', brand: 'Microsoft'},
  {name: 'ZenBook', brand: 'Asus'},
  {name: 'MacbookAir', brand: 'Apple'},
];

const apples = devices.filter((el, i) => {
  console.log(i);
  return el.brand === 'Apple';
});

console.log(apples);
//출력되는 값
0
1
2
3
4
5
(2) {...}, {...}

const myLaptop = devices.find((el, i) => {
  console.log(i); 
  return element.name === 'Apple';
});

console.log(myLaptop);
//출력되는 값
0
1
{name: "MacbookPro", brand: "Apple"}

filter 메소드는 조건을 만족하는 모든 값을 모아야 하기 때문에 배열의 모든 인덱스가 콘솔에 다 출력되었고, find 메소드는 조건을 만족하는 하나의 요소만 찾으면 되니까 단 두번의 인덱스만 콘솔에 출력되면서 콜백함수가 두번만 실행되고 종료되었다는걸 확인 할 수 있다.

+ 상황에 따라서 존재하지 않는 요소를 찾는다거나 가장 마지막에 위치해 있는 요소를 찾는다면 결국엔 filter 메소드와 반복횟수가 같아질 수 있다. 존재하지 않는요소를 찾으면 처음부터 마지막 인덱스까지 돈 후 undefined 값이 출력된다.

'코린이 개념잡기 > JavaScript' 카테고리의 다른 글

배열 메소드 Ⅳ (reduce)  (0) 2024.12.19
배열 메소드 Ⅲ (some, every)  (0) 2024.12.19
배열 메소드 Ⅰ (forEach, map)  (0) 2024.12.19
에러와 에러 객체  (1) 2024.12.18
구조 분해 Destructuring  (0) 2024.12.17

forEach 메소드

배열의 요소를 하나씩 살펴보면서 반복 작업을 하는 메소드이다. forEach 메소드는 첫 번째 아규먼트로 콜백 함수를 전달받는데, 콜백 함수의 파라미터에는 각각 배열의 요소, index, 메소드를 호출한 배열이 전달된다. (index와 array는 생략가능, 파라미터 하나는 반드시 작성되어야 하는데 배열의 요소는 반드시 작성해야한다.)

const numbers = [1, 2, 3];

numbers.forEach((element, index, array) => {
  console.log(element); // 순서대로 콘솔에 1, 2, 3이 한 줄씩 출력된다.
});
//for...of 문과 비교해보기
const members = ['지철', '동욱', '요셉', '민지'];

//for...of문
for (let member of members) {
  console.log(`${member}님이 입장하셨습니다.`);
};

//forEach문
members.forEach(function (member) {
  console.log(`${member}님이 입장하셨습니다.`);
});

//forEach문 화살표함수로 반환하기
members.forEach((member) => {
  console.log(`${member}님이 입장하셨습니다.`);
});

//출력되는 값은 모두 같다
지철님이 입장하셨습니다.
동욱님이 입장하셨습니다.
요셉님이 입장하셨습니다.
민지님이 입장하셨습니다.

forEach문에 작성된 function (member)에서 member 파라미터는 for...of 문의 let member of members에 member 변수와 역할이 같다.

//인덱스 활용하기
const firstNames = ['범수', '얼', '효신', '수'];
const lastNames = ['김', '나', '박', '이'];
//다른 배열과 함께 활용할 때 같은 인덱스의 요소를 매칭할 수 있다.

firstNames.forEach((firstName, i, arr) => {
  console.log(`${lastNames[i]${firstName}님이 입장하셨습니다.}`);
  //배열 활용하기
  console.log(arr);
});

//출력되는값
김범수님이 입장하셨습니다.
['범수', '얼', '효신', '수']
나얼님이 입장하셨습니다.
['범수', '얼', '효신', '수']
박효신님이 입장하셨습니다.
['범수', '얼', '효신', '수']
이수님이 입장하셨습니다.
['범수', '얼', '효신', '수'] //forEach 메소드를 호출한 배열이 전달된 모습

+ 변수에 담지않고 배열값 자체에 forEach 메소드를 활용하는 경우도 있다. 상황에 따라서 콜백 함수 내에서 해당 배열이 필요할 때 활용 가능하다. (firstNames.forEach => ['범수', '얼', '효신', '수'].forEach)

Map 메소드

forEach와 비슷하게 배열의 요소를 하나씩 살펴보면서 반복 작업을 하는 메소드이다. 단, 첫 번째 아규먼트로 전달하는 콜백 함수가 매번 리턴하는 값들을 모아서 새로운 배열을 만들어 리턴하는 특징이 있다.

const numbers = [1, 2, 3];
const twiceNumbers = numbers.map((element, index, array) => {
  return element * 2;
});

console.log(twiceNumbers); // (3) [2, 4, 6]
//forEach문 대신 map 사용해보기
const firstNames = ['범수', '얼', '효신', '수'];
const lastNames = ['김', '나', '박', '이'];

firstNames.map((firstName, i, arr) => {
  console.log(`${lastNames[i]${firstName}님이 입장하셨습니다.}`);
  console.log(arr);
});

//출력되는값
김범수님이 입장하셨습니다.
['범수', '얼', '효신', '수']
나얼님이 입장하셨습니다.
['범수', '얼', '효신', '수']
박효신님이 입장하셨습니다.
['범수', '얼', '효신', '수']
이수님이 입장하셨습니다.
['범수', '얼', '효신', '수']

map 메소드는 콜백함수 내에서 리턴문을 작성하게되면 각각의 리턴값으로 구성된 새로운 배열이 결과로 리턴된다.

const firstNames = ['범수', '얼', '효신', '수'];
const lastNames = ['김', '나', '박', '이'];

firstNames.map((firstName, i) => {
  return lastNames[i] + firstName;
});

//그래서 이 메소드에 호출한 결과를 변수에 담아서 콘솔에 출력해보면
const fullNames = firstNames.map((firstName, i) => {
  return lastNames[i] + firstName;
});

//arrow function으로 변환했을 때(더욱 간결한 작성)
//const fullNames = firstNames.map((firstName, i) => lastNames[i] + firstName);

console.log(fullNames);

//결과값
(4) ["김범수", "나얼", "박효신", "이수"]
//작성한 콜백 함수의 리턴값들로 구성된 배열이 출력된다.

forEach 메소드는 리턴값이 없기 때문에 변수에 담았을 땐 항상 undefined 값을 갖는다.

const fullNames = firstNames.map((firstName, i) => lastNames[i] + firstName);

console.log(fullNames);

//출력
undefined

단순히 배열의 반복작업이 필요할 땐 forEach를, 반복 작업을 통해서 새로운 배열이 필요한 경우엔 map 메소드를 활용한다.

+ 두 메소드의 최대 반복 횟수는 메소드를 처음 호출할 때 그 당시 요소의 개수이다. forEach나 map 메소드는 콜백 함수 내부에서 반복중인 배열을 편집할 수도 있다. 매번 반복할 때마다 배열의 새로운 요소를 추가하게 되면 무한루프에 빠질 거라고 예상할 수도 있지만 실제로 동작해보면 배열의 요소 갯수만큼만 동작하고 끝난 모습을 확인 할 수 있다.

const members = ['나래', '가영', '종윤', '세영'];

members.forEach((member) => {
  console.log(`${member}님이 입장하셨습니다.`);
  members.push('김태호');
});

console.log(members);

//출력되는 값
나래님이 입장하셨습니다.
가영님이 입장하셨습니다.
종윤님이 입장하셨습니다.
세영님이 입장하셨습니다.
(8) ["나래", "가영", "종윤", "세영", "김태호", "김태호", "김태호", "김태호"]

반복 중에 배열의 길이가 줄어든다면 반복 횟수도 함께 줄어든다.

const members = ['나래', '가영', '종윤', '세영'];

members.forEach((member) => {
  console.log(`${member}님이 입장하셨습니다.`);
  members.pop();
});

console.log(members);

//출력되는 값
나래님이 입장하셨습니다.
가영님이 입장하셨습니다.
(2) ["나래", "가영"]

'코린이 개념잡기 > JavaScript' 카테고리의 다른 글

배열 메소드 Ⅲ (some, every)  (0) 2024.12.19
배열 메소드 Ⅱ (filter, find)  (0) 2024.12.19
에러와 에러 객체  (1) 2024.12.18
구조 분해 Destructuring  (0) 2024.12.17
모던한 프로퍼티 표기법  (1) 2024.12.17

자바스크립트에서 에러가 발생하면 그 순간 프로그램 자체가 멈춰버리고 이후의 코드가 동작하지 않는다.

console.log('시작!');

const title = '해피 크리스마스!';
console.log(title);

console.log('끝!');

//출력 값
시작!
해피 크리스마스!
끝!

//하지만 만약 실수로 코드를 잘못 입력하게 되면..?

console.log('시작!');

const title = '해피 크리스마스!';
console.log(title);
console.log(christmas); //선언하지 않은 변수 or 함수를 값으로 입력

console.log('끝!');

//출력 값
시작!
해피 크리스마스!
Uncaught ReferenceError: christmas is not defined at index.js:19
//에러가 발생한 순간 프로그램이 멈춰버려서 이후에 나와야 하는 끝!은 출력되지 못한다.

자바스크립트에서는 에러가 발생하면 에러에 대한 정보를 name과 message라는 프로퍼티로 담고 있는 에러 객체가 만들어지는데, 대표적인 에러 객체는 SyntaxError, ReferenceError, TypeError 이다.

//존재하지 않는 함수나 변수를 호출할 때 발생되는 레퍼런스에러(ReferenceError)
//Uncaught ReferenceError: christmas is not defined at index.js:1

//잘못된 방식으로 자료형을 다루려고 할 때 발생되는 타입에러(TypeError)
const title = '코끼리';
console.log(title());

//Uncaught TypeError: title is not a function at index.js:6

//문법에 맞지 않을 때 발생되는 신택스에러(SyntaxError), 코드를 실행시키기도 전에 에러를 발생시킨다.(코드실행X)
const ti-tle = '코끼리';
console.log(title);

//Uncaught SyntaxError: Missing initializer in const declaration index.js:11

에러 객체는 직접 만들 수도 있다. new 키워드와 에러 객체 이름을 딴 함수를 통해 에러 객체를 만들 수 있고, throw 키워드로 에러를 발생시킬 수 있다.

throw new TypeError('타입 에러가 발생했습니다.');

try...catch문

try {
  // 실행할 코드
} catch (error) {
  // 에러 발생 시 동작할 코드
}

try...catch문은 자바스크립트에서 대표적인 에러 처리 방법이다.
try문 안에서 실행할 코드를 작성하고, try문에서 에러가 발생한 경우에 실행할 코드를 catch 문 안에 작성하면 되는데, 이 때 try문에서 발생한 에러 객체가 catch문의 첫 번째 파라미터로 전달된다. 만약, try문에서 에러가 발생하지 않을 경우 catch문의 코드는 동작하지 않는다.

try...catch문은 실행이 가능한 코드 내에서 에러를 다룬다. SyntaxError처럼 코드를 실행조차 하지 않는 에러는 try...catch문을 활용할 수 없다. 실행이 가능한 코드에서 발생한 에러를 예외(Exception)이라고 하는데, 실행가능한 코드에서 발생한 에러를 다루는 과정을 가리켜서 예외처리(Exception Handling)라고 한다.

try {
  console.log('에러 전');
  
  const codeName = 'Kelly';
  console.log('codeName');
  
  coneName = 'Alex'; //에러가 발생하는 지점
  
  const language = 'JavaScript';
  console.log(language);
} catch (error) {
  console.log('에러 후');
};

//출력 되는 값
에러 전
Kelly
에러 후

try 블록 내에서 에러가 발생된 시점 이후로는 실행되지 않고, 에러가 발생하면 catch문이 실행됐다. 만약 에러가 발생하는 지점을 없애준다면 코드는

try {
  console.log('에러 전');
  
  const codeName = 'Kelly';
  console.log('codeName');
  
  const language = 'JavaScript';
  console.log(language);
} catch (error) {
  console.log('에러 후');
};

//출력 되는 값
에러 전
Kelly
JavaScript

"에러 후"가 출력되지 않는다. try 문 안에 에러가 없기 때문에 catch문 안의 코드가 동작하지 않은것이다.

function printMembers(members) {
  for (const member of members) {
    console.log(member);
  }
};

const teamA = ['영진', '정윤', '혜미', '수진'];
printMembers(teamA);

const codeName = { name: 'Kelly' };
printMembers(codeName);

const teamB = ['종훈', '철수', '태희', '재석'];
printMembers(teamB);

//출력되는 값
영진
정윤
혜미
수진
//Uncaught TypeError: title is not a function at index.js:11

위 코드를 예시로 봤을 때 printMembers(codeName); 에러로 인해서 그 아래 코드는 실행되지 않고 프로그램이 멈췄다. 이런상황에서 콘솔창에 teamB에 접근해봐도 변수 teamB는 선언조차 되지 않았다.

콘솔창에서 보는 에러 상황

이럴 때 함수 내부에 try...catch문을 활용하게 되면 try 문 안에서 에러가 발생하더라도 catch문에서 에러 객체를 다루기 때문에 프로그램을 멈추지 않고 그 이후에 코드들을 안전하게 실행시킬 수가 있다

function printMembers(members) {
  try {
    for (const member of members) {
      console.log(member);
    }
  } catch (err) {
    console.error(err);
    alert(`${err.name}가 발생했습니다. 콘솔창을 확인해 주세요.`);
  }
};

const teamA = ['영진', '정윤', '혜미', '수진'];
printMembers(teamA);

const codeName = { name: 'Kelly' }; //배열이 아닌 객체값 사용, 객체는 for...of 문을 사용할 수 없다.
printMembers(codeName);

const teamB = ['종훈', '철수', '태희', '재석'];
printMembers(teamB);

방금 전과는 다르게 에러가 발생했다고 alert 창이 알려준다. 

콘솔창도 확인해보면 teamA의 요소들은 정상적으로 출력이 됐고, 에러 메세지도 똑같이 출력이 되긴 했지만, 에러가 발생한 다음에도 catch문을 통해 에러를 다뤘기 때문에 프로그램이 멈추지 않는다. (훨씬 안정적으로 프로그램을 만들 수 있다.)

그리고 try...catch문에서 에러의 유무와 상관없이 항상 동작해야할 코드가 필요하다면 finally문을 활용할 수 있다.

try {
  // 실행할 코드
} catch (error) {
  // 에러가 발상했을 때 실행할 코드
} finally {
  // 항상 실행할 코드
}

다시 말하자면, try문에서 어떤 코드를 실행할 때 에러 여부와 상관 없이 항상 실행할 코드를 작성하는 것이다.

function printMembers(...members) {
  for (const member of members) {
    console.log(member);
  }
}

try {
  printMembers('영훈', '윤수', '동욱');
} catch (err) {
  alert('에러가 발생했습니다!');
  console.error(err);
} finally {
  const end = new Date();
  const msg = `코드 실행을 완료한 시각은 ${end.toLocaleString()}입니다.`;
  console.log(msg);
}

+ finally문에서 에러가 발생한 경우에는 다시 그 위에 있는 catch문으로 넘어가진 않는다. 마아아안약에 finally문에서도 에러 처리가 필요한 경우에는 try...catch문을 중첩해서 활용하는 방법이 있다.

try {
  try {
    // 실행할 코드
  } catch (err) {
    // 에러가 발생했을 때 실행할 코드
  } finally {
    // 항상 실행할 코드
  }
} catch (err) {
  // finally문에서 에러가 발생했을 때 실행할 코드
}

'코린이 개념잡기 > JavaScript' 카테고리의 다른 글

배열 메소드 Ⅱ (filter, find)  (0) 2024.12.19
배열 메소드 Ⅰ (forEach, map)  (0) 2024.12.19
구조 분해 Destructuring  (0) 2024.12.17
모던한 프로퍼티 표기법  (1) 2024.12.17
Spread 구문  (0) 2024.12.16

배열과 객체와 같이 내부에 여러 값을 담고 있는 데이터 타입을 다룰 때 Destructuring 문법을 활용하면, 배열의 요소나 객체의 프로퍼티 값들을 개별적인 변수에 따로 따로 할당해서 다룰 수가 있다.

// 배열 구조분해 Array Destructuring
const members = ['코딩하는지용', '글쓰는유나', '편집하는민환'];

const macbook = members[0]; //지용
const macbook = members[1]; //유나
const macbook = members[2]; //민환
//위 세 줄 코드를 구조분해 문법으로 작성하면 아래의 코드 한줄과 같다.
const [macbook, ipad, coupon] = members;
//할당 연산자 members의 왼편에 변수의 이름들이 배열로 선언되어 있고, 
//members 배열 자체를 할당해 버린 모습을 하고 있다. 즉, 배열을 분해해서 하나씩 할당하는 것.

//할당하는 값이 없거나 배열의 형식이 아닌 경우엔 에러가 발생한다.
//const [macbook, ipad, coupon]; 혹은 const [macbook, ipad, coupon] = 123;

console.log(macbook); // 코딩하는지용
console.log(ipad); // 글쓰는유나
console.log(coupon); // 편집하는민환

함수에서 default parater, rest parameter를 다루듯이 Destructuring 문법을 활용할 때도 기본값과 rest 문법을 활용할 수 있다.

// Array Destructuring
const members = ['코딩하는지용', '글쓰는유나', undefined, '편집하는민환', '촬영하는준하'];
const [macbook, ipad, airpod = '녹음하는규식', ...coupon] = members;

console.log(macbook); // 코딩하는지용
console.log(ipad); // 글쓰는유나
console.log(airpod); // 녹음하는규식
console.log(coupon); // (2) ["편집하는민환", "촬영하는준하"]
//rest parameter와 마찬가지로 나머지 요소를 가져오기 때문에 항상 마지막 변수에만 활용할 수 있다.

선언된 변수의 개수와 배열의 길이가 같아야 할 필요는 없다. 할당하는 배열의 길이가 길더라도, 인덱스에 따라 순서대로 할당이 되기 때문에 길이가 넘치는 요소는 어느 변수에도 할당되지 않는다. 배열의 길이가 적을 경우에는 남은 변수에 undefined 값이 반환된다.

배열의 구조분해 문법은 변수에 할당된 값을 서로 교환할 때도 활용할 수가 있다.

let macbook = '주원';
let ipad = '희준';

console.log('MacBook 당첨자:', macbook); //Macbook 당첨자: 주원
console.log('iPad 당첨자:', ipad); //iPad 당첨자: 희준

//배열 구조분해를 사용하지 않을 때 두 값을 교환해야 하는 경우
let temp = macbook; //임시로 값을 담아둘 변수를 만들어 활용했다.
macbook = ipad;
ipad = temp;

console.log('MacBook 당첨자:', macbook); //Macbook 당첨자: 희준
console.log('iPad 당첨자:', ipad); //iPad 당첨자: 주원

//배열 구조분해를 활용하는 경우. (할당연산자는 오른쪽 값을 왼쪽의 피연산자에 할당하는 동작을 한다.)
[macbook, ipad] = [ipad, macbook];

console.log('MacBook 당첨자:', macbook); //Macbook 당첨자: 희준
console.log('iPad 당첨자:', ipad); //iPad 당첨자: 주원

객체도 배열과 크게 다르진 않지만 객체는 인덱스가 아니라 프로퍼티 네임으로 여러 값들을 구분한다. 배열 구조분해에서 대괄호를 감쌌던 것처럼 객체를 분해할 때는 중괄호로 변수를 감싸준다.

// 객체 구조분해 Object Destructuring
const macbookPro = {
  title: '맥북 프로 16형',
  price: 3690000,
};

const title = macbookPro.title;
const price = macbookPro.price;
//위 코드 두 줄을 아래 한줄로 객체 구조분해 할 수 있다.
const { title, price } = macbookPro;

console.log(title); // 맥북 프로 16형
console.log(price); // 3690000

그외에는 배열의 구조분해처럼 존재하는데 예를 들어 객체에 존재하지 않는 프로퍼티 네임으로 변수가 선언이 되어 있으면 undefined 값이 할당 되고, 할당연산자를 통해서 기본값을 지정해 줄수도 있다. 

+ 선언된 변수의 개수와 배열의 길이가 같아야 할 필요는 없다. 할당하는 배열의 길이가 길더라도, 인덱스에 따라 순서대로 할당이 되기 때문에 길이가 넘치는 요소는 어느 변수에도 할당되지 않는다. 배열의 길이가 적을 경우에는 남은 변수에 undefined 값이 반환된다.

// Object Destructuring
const macbookPro = {
  title: '맥북 프로 16형',
  price: 3690000,
  memory: '16 GB 2667 MHz DDR4',
  storage: '1TB SSD 저장 장치',
};

const { title, price, color = 'silver', ...rest } = macbookPro;

console.log(title); // 맥북 프로 16형
console.log(price); // 3690000
console.log(color); // silver
console.log(rest); // {memory: "16 GB 2667 MHz DDR4", storage: "1TB SSD 저장 장치"}

...rest 처럼 나머지 프로퍼티를 하나의 객체로 모을 수도 있는데, 만약 이것을 제외하면 변수 이름은 항상 프로퍼티 네임과 동일해야 하는 걸까?

// Object Destructuring
const macbookPro = {
  title: '맥북 프로 16형',
  price: 3690000,
  memory: '16 GB 2667 MHz DDR4',
  storage: '1TB SSD 저장 장치',
};

const { title: product, price, color = 'silver', ...rest } = macbookPro;
//바꿔주고싶은 프로퍼티 네임: 바꿀 프로퍼티 네임

console.log(title); //Error!!
console.log(product); // 맥북 프로 16형

바꿔주고싶은 프로퍼티 네임: 바꿀 프로퍼티 네임으로 작성해주면 새로운 이름의 변수를 선언 할 수 있다. 코드를 실행해봤을 때 console.log(title)은 에러가 발생하지만 console.log(product)로 실행해보면 title 프로퍼티가 잘 할당되어 있는 것을 확인 할 수 있다.

//객체 내부의 프로퍼티 네임이 변수 이름으로 사용할 수 없는 경우
const launching = {
  title: '서울 어린이 동물원',
  thema: '동물원',
  price: 40000,
  operatingHours: '9 to 5',
  'serial-num': 'ABCDEFGHIJKLMNOP'
};
//따옴표를 활용하면 중간에 하이픈이 있어서 변수로 사용할 수 없는 이름도 프로퍼티 네임으로 사용할 순 있지만
//구조분해를 할 때는 반드시 새로운 이름으로 변수를 선언해야 한다.

const {title, thema, price, operatingHours, 'serial-num':serialNum } = launching;

//그리고 위 방식말고도 아래 방식으로 변수의 새로운 이름을 선언할수도 있다.

const propertyName = ''serial-num';
const { [propertyName]: serialNum } = launching;

'코린이 개념잡기 > JavaScript' 카테고리의 다른 글

배열 메소드 Ⅰ (forEach, map)  (0) 2024.12.19
에러와 에러 객체  (1) 2024.12.18
모던한 프로퍼티 표기법  (1) 2024.12.17
Spread 구문  (0) 2024.12.16
조건부 연산자(삼항 연산자)  (1) 2024.12.16

ES2015 이후부터는 자바스크립트에서 변수나 함수를 활용해서 프로퍼티를 만들 때 프로퍼티 네임과 변수나 함수 이름이 같다면 축약해서 사용할 수 있다.

function sayHi() {
  console.log('Hi!');
}

const title = 'code';
const birth = 2000;
const job = '인플루언서';

//때로는 객체를 만들 때 변수에 할당된 값을 활용해서 프로퍼티를 만들 수도 있다.
const user = {
  title: title, //활용할 변수의 이름과 프로퍼티 네임이 똑같다면
  birth, //이렇게 하나만 작성하는 표현이 가능하다.
  job, 
  sayHi,
};

console.log(user); // {title: "code", birth: 2000, job: "인플루언서", sayHi: ƒ}

그리고 메소드를 작성할 때도 다음과 같이 function 키워드를 생략할 수가 있다.

//getFullName: function() {
//    return `${this.firstName} ${this.lastName}`;
//  },
//: function을 생략할 수 있다.

const user = {
  firstName: 'Tess',
  lastName: 'Jang',
  getFullName() {
    return `${this.firstName} ${this.lastName}`;
  },
};

console.log(user.getFullName()); // Tess Jang

뿐만아니라 아래 코드와 같이 표현식을 대괄호로 감싸주게 되면, 표현식의 값을 프로퍼티 네임으로 쓸 수 있다.

//계산된 속성명(computed property name)
const usr = {
  [표현식]: 값,
};

const propertyName = 'birth';
const getJob = () => 'job';

const codeTest = {
  ['topic' + 'name']: 'Modern JavaScript',
  [propertyName]: 1998, //변수에 담긴 값을 사용하거나
  [getJob()]: '프로그래밍 강사' //함수의 리턴값을 사용할 수도 있다.
};

console.log(codeTest); //{topicName: "Modern JavaScript", birth: 1998, job: "프로그래밍 강사"}

'코린이 개념잡기 > JavaScript' 카테고리의 다른 글

에러와 에러 객체  (1) 2024.12.18
구조 분해 Destructuring  (0) 2024.12.17
Spread 구문  (0) 2024.12.16
조건부 연산자(삼항 연산자)  (1) 2024.12.16
함수  (0) 2024.12.15

펼치다 라는 spread의 의미처럼, 여러개의 값을 하나로 묶은 배열을 다시 각각의 개별값으로 펼치는 문법이다.

//spread 구문(spread syntax)
const number = [1, 2, 3];
console.log(number); // (3) [1, 2, 3]  배열이 출력된다.
console.log(...number); //1, 2, 3

//rest parameter
const sumAll = (...args) => {
  let sum = 0;
  for (arg of args) {
    sum += arg;
  }
  return sum;
};

console.log(sumAll(1, 2, 3, 4)); //10

출력되는 창

배열로 묶어있던 값들이 괄호가 벗겨지고 각각의 개별값으로 펼쳐졌다. 그런데 잘 생각해보면 Rest parameter를 만들때도 '...'을 사용했다. 얼핏 비슷한것 같지만 Rest parameter는 여러 개의 아규먼트를 하나의 파라미터로 묶는방식이고, Spread 구문은 하나로 묶여 있는 값을 각각의 개별 값으로 펼치는 방식이다. 그래서 하나의 값으로 평가되는게 아니라 여러 값의 목록으로 평가된다.

const webPublishing = ['HTML', 'CSS'];
const interactiveWeb = [...webPublishing, 'JavaScript'];

console.log(webPublishing); //(2) ['HTML', 'CSS']
console.log(interactiveWeb); //(3) ['HTML', 'CSS', 'JavaScript']
//spread 구문을 활용하면 조금 더 간단하고 직관적이게 배열을 다룰 수 있다.

const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];

const arr3 = [...arr1, ...arr2];
console.log(arr3); //(6) [1, 2, 3, 4, 5, 6]

const latte = {
  esspresso: '30ml',
  milk: '150ml'
};

const cafeMocha = {
  ...latte,
  chocolate: '20ml',
}

console.log(latte); // {esspresso: "30ml", milk: "150ml"}
console.log(cafeMocha); // {esspresso: "30ml", milk: "150ml", chocolate: "20ml"}


//여러개의 파라미터가 있는 함수를 호출할 때 배열을 펼쳐서 각각의 아규먼트로 사용할 수 있다.
const introduce - (name, birth, job) => {
  console.log(`안녕하세요! 반갑습니다!`);
  console.log(`저는 ${name}입니다.`);
  console.log(`${birth}년 생이고,`);
  console.log(`직업은 ${job}입니다.`);
};

const myArr = ['지니', 1992, '고등학교 교사'];
introduce(...myArr); //함수를 호출할 때 아규먼트로 활용도 가능
//spread 구문 자체를 값으로 오해하면 안된다! 여러개의 값이 각각 매칭되는 상황이기에 가능

Spread 구문은 배열이나 객체를 복사하거나 혹은 복사해서 새로운 요소들을 추가할 때 유용하게 활용할 수 있다. 참고로 배열은 객체로 펼칠 수 있지만 객체는 배열로 펼칠 수 없다.

//하나의 값을 가진 배열을 펼쳤다고 하더라도 괄호가 벗겨지고 하나의 값으로 평가되는게 아니라 오류가 발생한다.
const numbers =  [1];
const number = ...number; // TypeError!

//배열을 펼쳐서 객체에 담으면 
const members = ['태호', '종훈', '우재'];
const newObject = { ...members };

console.log(newObject); // {0: "태호", 1: "종훈", 2: "우재"}
//0번부터 시작하는 배열의 인덱스가 프로퍼티 네임이 되서 객체가 만들어진다.

//객체는 배열로 펼칠 수 없다.
const topic = {
  name: '모던 자바스크립트',
  language: 'JavaScript', 
}
const newArray = [...topic]; // TypeError!

객체를 spread할 때는 반드시 객체를 표현하는 중괄호 안에서 활용해야 한다.

'코린이 개념잡기 > JavaScript' 카테고리의 다른 글

구조 분해 Destructuring  (0) 2024.12.17
모던한 프로퍼티 표기법  (1) 2024.12.17
조건부 연산자(삼항 연산자)  (1) 2024.12.16
함수  (0) 2024.12.15
null 병합 연산자 (??)  (0) 2024.12.15

조건 연산자 (Conditional operator)이면서 삼항 연산자 (Ternary operator)라고도 불리는 이 연산자는 자바스크립트에서 세 개의 피연산자를 가지는 유일한 연산자이다.

if문과 같은 원리로 조건에 따라 값을 결정할 때 활용되는데

//조건 ? truthy 할 때 표현식 : falsy 할 때 표현식
const cutOff = 80;

function passChecker(score) {
  return score > cutOff ? '합격입니다!' : '불합격입니다!';
};

//score > cutOff 가 truthy하다면 합격입니다를, falsy하면 불합격입니다를 return

console.log(passChecker(75)); //함수를 호출하는 점수가 75점이니까 불합격이 return된다.

//화살표 함수로 표현해보면
const passChecker = (score) => score > cutOff ? '합격입니다!' : '불합격입니다!';

console.log(passChecker(90)); //합격이 출력된다.

간단한 조건식의 경우에는 if문 보다 훨씬 더 간결하게 표현할 수 있는 장점이 있지만 내부에 변수나 함수를 선언한다거나 반복문 같은 표현식이 아닌 문장은 작성할 수 없다는 한계가 있기 때문에 if문을 완벽하게 대체할 수는 없다.

'코린이 개념잡기 > JavaScript' 카테고리의 다른 글

모던한 프로퍼티 표기법  (1) 2024.12.17
Spread 구문  (0) 2024.12.16
함수  (0) 2024.12.15
null 병합 연산자 (??)  (0) 2024.12.15
AND와 OR 연산자 심화  (0) 2024.12.15

 함수 선언(function declaration)

자바스크립트에서 함수는 다양한 방식으로 선언할 수 있는데, 가장 일반적인 방법은 function 키워드를 통해 함수를 선언하는 방식이고, 

// 함수 선언
function 함수이름(파라미터) {
  동작
  return; 리턴값
};

function sayHi() {
  console.log('Hi!');
};

다른 하나는 함수 선언을 변수에 할당하는 방식(함수 표현식 (function expression))이다. 

//함수 표현식
const printCode = function () {
  console.log('Code World!');
};

printCode();

 

자바스크립트에서 함수는 값으로 취급될 수도 있기 때문에 변수에 할당해서 함수를 선언할 수도 있다. 함수선언을 변수에 할당하는 모습만 함수 표현식이라고 오해할 수 있는데, 

// 변수에 할당해서 활용
const printJS = function () {
  console.log('JavaScript');
};

// 객체의 메소드로 활용
const codeLove = {
  printTitle: function () {
    console.log('Code');
  }
}

// 콜백 함수(callback function, 다른 함수의 파라미터에 전달된 함수)로 활용
myBtn.addEventListener('click', function () {
  console.log('button is clicked!');
});

// 고차 함수(higher order function, 변수에 호출된 값 할당해서 활용)로 활용
function myFunction() {
  return function () {
    console.log('Hi!?');
  };
};
//이중 괄호를 사용해서 고차함수를 바로 호출할수도 있다.
myFunction()();

파라미터로 함수를 선언해서 전달한 콜백함수로 활용하는 모습도 결과적으로는 함수선언을 값처럼 활용한다는 점에서 함수 표현식이라고 할 수 있다.

✅함수 표현식은 변수에 할당하는것이 포인트가 아니라 함수 선언을 값처럼 사용하는 방식이 포인트다.

함수 선언과 함수 표현식의 차이

//함수 선언
printCode(); //Welcome Coding World

function printCode() {
  console.log('Welcome Coding World');
};

함수 선언보다 먼저 함수를 호출했는데도 문제 없이 코드가 잘 동작한다. 선언문이 위쪽으로 끌어올려지는 현상을 호이스팅(Hoisting)이라고 한다.

//함수 표현식
printCode(); //ReferenceError

const printCode = function() {
  console.log('Welcome Coding World');
};

반면 함수 표현식은 변수 특성상 선언 이전에 접근할 수가 없다.

//함수 선언
function printCode() {
  function printJS() {
    console.log('JavaScript');
  }
  console.log('Hello Code World');
  printJS();
};

printCode(); //Hello Code World, JavaScript
printJS(); //ReferenceError

함수 선언은 변수의 var 키워드 처럼 함수 스코프를 가진다. 함수 안에 선언된 함수는 함수 밖에서 호출할 수 없지만 함수가 아닌 다른 코드블록에서 함수 선언을 하게 되면 모두 전역적으로 호출이 가능해진다.

//함수가 아닌 다른 코드블록에서 함수 선언을 해서 전역적으로 호출이 가능해진 모습
const x = 4;

if (x < 5) {
  function printJS() {
    console.log('JavaScript');
  }
};

{
  function printCode() {
    console.log('I love Coding');
  };
}

printCode(); //I love Coding
printJS(); //JavaScript

반면에 함수 표현식의 경우에는 할당된 변수에 따라 스코프(scope)가 결정된다.

var printJS = function () {
  console.log('JavaScript');
};

let printHi = function () {
  console.log('Hi');
};

const printCode = function () {
  conosole.log('Coding');
};
함수 선언 함수 표현식
-코드의 가독성
-변수 선언과 함수선언 명확하게 구분 가능
-함수 호출 자유로움
-반드시 선언 이후에 호출 가능
-가독성 good
-코드의 흐름 더 쉽게 파악 가능
-변수의 스코프도 활용 가능

일반적으로 개념을 설명할 때는 표현식보다 선언 부분이라는 의미가 좀 더 명확하게 구분되는 함수 선언이 보편적으로 사용된다.


파라미터(Parameter)의 기본 값

함수를 호출할때 함수의 밖에서 안쪽으로 다양한 값들을 전달받고자 한다면 파라미터를 활용해야한다.

자바스립트에서 함수의 파라미터는 할당 연산자로 기본값을 가질 수가 있다. 기본값이 있는 파라미터는 함수를 호출할 때 아규먼트를 전달하지 않으면, 함수 내부의 동작은 이 파라미터의 기본값을 가지고 동작하게 된다.

//  (name)이 파라미터이다.
function greeting(name) {
  console.log(`Hi! My name is ${name}!`);
}

//파라미터를 활용하면 전달하는 값에 따라서 다양한 결과로 동작하는 모습을 확인 할 수 있다.
greeting('Anna'); //Hi My name is Anna!
greeting('Tom'); //Hi My name is Tom!
greeting(); //Hi My name is Undefined!

// 파라미터 기본값
function sayHi(name = 'kelly') {
  console.log(`Hi! ${name}`);
}

sayHi('JavaScript'); // Hi! JavaScript
sayHi(); // Hi! kelly


//아규먼트가 파라미터로 전달될 때는 파라미터의 기본값과는 관계없이 함수를 호출할 때 작성한 순서 그대로 전달한다.
//때문에 기본값이 필요한 파라미터는 가급적 오른쪽에 작성하는것이 권장된다.
function greeting(name = 'Jenny', interest = 'Javascript') {
  console.log(`Hi! My name is ${name}!`);
  console.log(`I Like ${interest}!`);
};

greeting(undefined, 'Python'); //아규먼트가 undefined값으로 전달될 때도 동작한다.

//출력되는 값
Hi! My nmae is Jenny!
I Like Python!

arguments 객체

자바스크립트 함수 안에는 arguments라는 독특한 객체가 존재한다. arguments 객체는 함수를 호출할 때 전달한 아규먼트들을 배열의 형태로 모아둔 유사 배열 객체인데 특히, 함수를 호출할 때 전달되는 아규먼트의 개수가 불규칙적일 때 유용하게 활용될 수 있다.

function printArguments() {
  // arguments 객체의 요소들을 하나씩 출력
  for (const arg of arguments) {
    console.log(arg); 
  }
}

printArguments('Young', 'Mark', 'Koby');

‼️파라미터와 아규먼트를 헷갈릴 수도 있다. 하지만 꼭 구분지어서 알아두는 것이 좋다.

function greeting(name) { //함수 선언 부분에서 소괄호 안에 작성되는것이 파라미터
  console.log(`Hi My naame is ${name}!`);
};

greeting('Anna'); //함수 호출부분에서 파라미터로 전달하는 값에 해당하는 부분이 아규먼트
greeting('Jenny');
greeting('Tom');

Rest Parameter

arguments 객체를 이용하는 것 말고도 불규칙적으로 전달되는 아규먼트를 다루는 방법이 있다. 파라미터 앞에 마침표 세 개를 붙여주면, 여러 개로 전달되는 아규먼트들을 배열로 다룰 수 있다.
그리고 arguments객체는 유사 배열이기 때문에 배열의 메소드를 활용할 수 없는 반면, rest parameter는 배열이기 때문에 배열의 메소드를 자유롭게 사용할 수 있다는 장점이 있다.

function printArguments(...args) {
  // args 객체의 요소들을 하나씩 출력
  for (const arg of args) {
    console.log(arg); 
  }
}

printArguments('Young', 'Mark', 'Koby');

rest parameter는 다른 일반 파라미터들과 함께 사용될 수도 있는데

//앞에 정의된 parameter에 아규먼트를 먼저 할당하고 (first, second)
//나머지 아규먼트(...other)를 배열로 묶는 역할을 하기 때문에 
//일반 파라미터와 사용될때는 가장 마지막에 작성되어야 한다.
function printRankingList(first, second, ...others) {
  console.log('코드잇 레이스 최종 결과');
  console.log(`우승: ${first}`);
  console.log(`준우승: ${second}`);
  for (const arg of others) {
    console.log(`참가자: ${arg}`);
  }
}

printRankingList('Tommy', 'Jerry', 'Suri', 'Sunny', 'Jack');

이름 그대로 앞에 정의된 이름 그대로 앞에 정의된 파라미터에 argument를 먼저 할당하고 나머지 argument를 배열로 묶는 역할을 하기 때문에 일반 파라미터와 함께 사용할 때는 반드시 가장 마지막에 작성해야 한다.

Arrow Function

arrow function은 익명 함수를 좀 더 간결하게 표현할 수 있도록 ES2015에서 새롭게 등장한 함수 선언 방식이다. arrow function은 이름이 없는 익명함수이기 때문에 일반적으로 어떤 이름을 가진 변수에 할당하거나, 다른 함수의 아규먼트로 선언할 때 주로 활용된다.
아래 코드와 같이 표현식으로 함수를 정의할 때 활용될 수도 있고 콜백 함수로 전달할 때 활용할 수도 있다.

// 화살표 함수 정의
const getTwice = (number) => {
  return number * 2;
};

// 콜백 함수로 활용
myBtn.addEventListener('click', () => {
  console.log('button is clicked!');
});

화살표 함수는 기존의 function 함수를 조금 더 간결하게 표현하고자 등장했기 때문에 상황에 따라서는 훨씬 더 짧게 표현될 수도 있다.

// 1. 함수의 파라미터가 하나 뿐일 때
const getTwice = (number) => {return number * 2;};

// 파라미터를 감싸는 소괄호 생략 가능 (파라미터가 두개 이상이거나 없을 때는 반드시 소괄호를 작성)
const getTwice = number => {return number * 2;};

// 2. 함수 동작 부분이 return문만 있을 때
const sum = (a, b) => {return a + b;};

// return문과 중괄호 생략 가능 
// (하지만 함수 내부에서 조건문이나 반복문, 변수의 값을 할당하는 것과 같이 
// return문 외에 다른 표현들이 더 필요하다면 중괄호와 return 키워드는 생략할 수 없다.)
const sum = (a, b) => a + b;

// 3. 함수 내부 동작이 return문 하나뿐이어도 값이 객체인 경우는 주의해서 사용해야한다.
const getCode = () => {
  return {name: 'Ann', };
};

//중괄호와 return 키워드를 생략하게 되면 에러가 발생한다.
const getCode = () => {name: 'Ann', }; //Error

//객체라고 작성한 중괄호를 함수의 동작 부분을 구분하는 중괄호로 해석하기 때문이다. 이 땐 소괄호로 한번 더 감싸주면 해결된다.
const getCode = () => ({name: 'Ann', }); //{name: Ann}

그리고 Arrow function이 일반 함수와 몇 가지 차이점이 있는데 가장 대표적인 차이점은 arguments 객체가 없고, this가 가리키는 값이 일반 함수와 다르다는 것이다.

this

자바스크립트에는 this라는 조금 특별한 키워드가 있다. 웹 브라우저에서 this가 사용될 때는 전역 객체, Window 객체를 가지게 된다. 하지만 객체의 메소드를 정의하기 위한 함수 안에선 메소드를 호출한 객체를 가리킨다.

//이렇게 사용해도 잘 동작하지만 (물론 여기서 user을 this로 바꿔 사용해도 충분히 사용가능하다.)
const user = {
  firstName: 'Tess',
  lastName: 'Jang',
  getFullName: function () {
    return `${user.firstName} ${user.lastName}`;
  },
};

console.log(user.getFullName()); // Tess Jang

//이 메소드를 다른 객체에도 적용하고 싶어서 험수 외부로 분리하면 동작에 어려움이 있다.
function getFullName() {
  return `${user.firstName} ${user.lastName}`
};

const user = {
  firstName: 'Tess',
  lastName: 'Jang',
  getFullName: getFullName
};

const admin = {
  firstName: 'Alex',
  lastName: 'Kim',
  getFullName: getFullName
};

console.log(user.getFullName()); // Tess Jang
console.log(admin.getFullName()); // Tess Jang

//getFullName의 동작부분에서 user 객체만 바라보기 때문에 admin 객체에서 메소드를 호출하더라도 user 프로퍼티를 사용한다.

function getFullName() {
  return `${this.firstName} ${this.lastName}`
};

const user = {
  firstName: 'Tess',
  lastName: 'Jang',
  getFullName: getFullName
};

const admin = {
  firstName: 'Alex',
  lastName: 'Kim',
  getFullName: getFullName
};

console.log(user.getFullName()); // Tess Jang
console.log(admin.getFullName()); // Alex Kim

위 상황에선 this 키워드가 유용하게 사용될 수 있다. 자바스크립트에서 this는 함수를 호출한 객체를 가리키는 키워드인것이다. 그래서 코드를 작성할 때 값이 미리 결정되는게 아니라 함수가 호출될 때 어떤 객체가 그 함수를 호출했는지에 따라 상대적으로 값이 변하게 된다.

//일반 함수와 Arrow function은 this를 다루는 방식이 서로 다르다.

//화살표 함수에서 this 값은 일반 함수처럼 호출한 대상에 따라 상대적으로 변하는게 아니라
//화살표 함수가 실행되기 직전에 유효한 this 값과 똑같은 값을 가지고 동작한다.

console.log(this); //window객체가 호출된다.

const printThis = () => { //여기 화살표 함수가 선언되기 직전의 this는 윗줄에 window 객체이다.
  console.log(this);
};

const myObj = {
  cotent: 'myObj',
  printThis: printThis
};

const otherObj = {
  cotent: 'otherObj',
  printThis: printThis
};

myObj.printThis(); //window 객체
otherObj.printThis(); //window 객체, 그래서 코드를 실행했을 때 이런결과가 출력되는 것이다.

//이런 객체 특징때문에 객체에 메소드를 만들 때는 화살표 함수보다 일반 함수가 조금 더 권장된다.

'코린이 개념잡기 > JavaScript' 카테고리의 다른 글

Spread 구문  (0) 2024.12.16
조건부 연산자(삼항 연산자)  (1) 2024.12.16
null 병합 연산자 (??)  (0) 2024.12.15
AND와 OR 연산자 심화  (0) 2024.12.15
Falsy & Truthy  (1) 2024.12.15

물음표 두개(??)를 사용해서 null 혹은 undefined 값을 가려내는 연산자이다.

const example1 = null ?? 'I';
const example2 = undefined ?? 'love';
const example3 = 'Coding' ?? 'JavaScript';

console.log(example1, example2, example3); // ?

예시 1과 2를 보면 nill 병합 연산자 왼편에 각각 null과 undefined가 있다. 연산자 왼편의 값이 null이나 undefined라면 연산자 오른편의 값이 리턴되고, 예시 3처럼 연산자 왼편 값이 null이나 undefined 값이 아니라면 연산자 왼편 값이 리턴되는 동작 방식이다.

결과적으로 출력되는 값은 "I love Coding"

const example1 = null ?? 'I'; // I
const example2 = undefined ?? 'love'; // love
const example3 = 'Coding' ?? 'JavaScript'; //Coding

console.log(example1, example2, example3); // I love Coding

OR 연산자와 비슷해보이는데 실제로도 상황에 따라 똑같이 동작할 수 있다.

const title1 = null || 'love cat';
const title2 = null ?? 'love dog';

console.log(title1); // love cat
console.log(title2); // love dog

하지만 null 병합 연산자는 왼쪽의 값이 nill이나 undefined인지 확인하고 OR 연산자는 왼쪽의 값이 falsy인지 확인하기 때문에 null이나 undefined가 아닌 falsy값을 활용할 때 결과가 서로 다르다.

const title1 = false || 'Merry Christmas!';
const title2 = false ?? 'Santa';

console.log(title1); // Merry Christmas!
console.log(title2); // false

const width1 = 0 || 150;
const width2 = 0 ?? 150;

console.log(width1); // 150
console.log(width2); // 0

'코린이 개념잡기 > JavaScript' 카테고리의 다른 글

조건부 연산자(삼항 연산자)  (1) 2024.12.16
함수  (0) 2024.12.15
AND와 OR 연산자 심화  (0) 2024.12.15
Falsy & Truthy  (1) 2024.12.15
새로운 데이터 타입과 특징  (1) 2024.12.15

+ Recent posts