[TIL] 210918

📝 오늘 한 것

  1. "false" VS false / array.flat() / 객체 지향 프로그래밍 / prototype / function.call() / array.filter() / && / array.includes() / array.push() / array.map()

  2. javascript-koans 풀이 완료


📖 학습 자료

  1. 생활코딩 객체 지향 프로그래밍 강의 1 ~ 12편(7.2)

📚 배운 것

🔎 javascript-koans

이전 풀이 이어서
풀면서 모르거나 헷갈렸던 부분 정리


1. AboutHigherOrderFunctions.js

1) "false" VS false

(1) var msg = "" + ((3 % 2) === 0);

var msg = "";

msg = msg + ((3 % 2) === 0);
// msg = "" + false;
// ""와 false를 더한 값을 변수 msg에 할당
console.log(msg);
// "false" (∵ "" + false === "false")

msg = msg + ((2 % 2) === 0);
// msg = "false" + true;
// "false"와 true를 더한 값을 변수 msg에 할당
console.log(msg);
// "falsetrue"

(2) var msg = "" + (3 % 2) === 0;

var msg = "";

msg = msg + (3 % 2) === 0;
// msg = "" + 1 === 0;
// ""와 1을 더한 값이 0과 일치하는지를 판단 후 true/false 값을 msg 변수에 할당
console.log(msg);
// false (∵ "1" !== 0)

msg = msg + (2 % 2) === 0;
// msg = false + 0 === 0;
// false와 0을 더한 값이 0과 일치하는지를 판단 후 true/false 값을 msg에 할당
console.log(msg);
// true (∵ console.log(false + 0); // 0 )

cf. boolean(불리언)

  • true/false 값을 갖는다
  • 자바스크립트에서 true는 1, false는 0과 같다고 표현되기도 한다
console.log(true); // true
console.log(true + 0); // 1
console.log(false); // false
console.log(false + 1); // 0

2) array.flat();

(1) 중첩된 배열 평탄화

var array = [[1, 2], [[3, 4], [5, 6]]];

var flat1 = array.flat();
console.log(flat1);
// [1, 2, [3, 4], [5, 6]]

var flat2 = array.flat(2);
console.log(flat2)
// [1, 2, 3, 4, 5, 6]

(2) 배열의 구멍 제거

var array = [1, 2, , 3, 4];

var flat = array.flat();
console.log(flat);
// [1, 2, 3, 4]

🔎 객체 지향 프로그래밍

AboutInheritance.js 풀다가 prototype 강의 듣고 옴
생활코딩 객체 지향 프로그래밍 강의 (1 ~ 12편(7.2)) 참고


1. 객체

서로 연관된
변수와 함수를
그룹핑 하고
이름을 붙인 것

2. 예약어 this

this가 속해 있는 메서드
가 속해 있는 객체를 가리킴

3. prototype(프로토타입)

1) 의미

  • 어휘적 의미 : 원형, 공통된 모습, 본래의 모습

  • 자바스크립트 : 프로토타입 기반 언어

2) 생성자 함수 안에서 메서드를 정의하는 경우

생성자를 이용해 객체를 생성할 때마다 메서드가 만들어져 메모리에 할당이 되기 때문에 메모리 효율이 좋지 않다

function Person (name, first, second) {
  this.name = name;
  this.first = first;
  this.second = second;

  // 이 부분이 kim, lee 등의 객체들을 생성할 때마다 새로 만들어져 메모리에 할당된다
  this.sum = function () {
    return this.first + this.second;
  }
}

var kim = new Person('kim', 10, 20);
var lee = new Person('Lee', 10, 10);

console.log(kim.sum()); // 30
console.log(lee.sum()); // 20

3) prototype 활용

한 번만 정의해 놓으면 되기 때문에 메모리가 비효율적으로 낭비되지 않는다

(1) 생성자를 이용해 생성한 모든 객체들의 메서드를 정의하는 방법

// 객체의 💡속성💡은 객체 생성자 함수에 정의해두고
function Person (name, first, second) {
  this.name = name;
  this.first = first;
  this.second = second;
}

// 효율성을 위해 객체의 💡메서드💡는 prototype을 이용해 따로 정의할 것
Person.prototype.sum = function () {
  return this.first + this.second;
}

var kim = new Person('kim', 10, 20);
var lee = new Person('Lee', 10, 10);

console.log(kim.sum()); // 30
console.log(lee.sum()); // 20

(2) 생성자를 이용해 생성한 객체들 중 어느 한 객체의 메서드만 바꾸는 방법

function Person (name, first, second) {
  this.name = name;
  this.first = first;
  this.second = second;
}

Person.prototype.sum = function () {
  return this.first + this.second;
}

var kim = new Person('kim', 10, 20);
var lee = new Person('Lee', 10, 10);

// 추가한 코드
kim.sum = function () {
  return 'modified: ' + (this.first + this.second);
} 

console.log(kim.sum()); // 'modified: 30'
console.log(lee.sum()); // 20

자바스크립트가 kim.sum()의 값을 구해주는 과정

  • 먼저, 객체 kim에 sum()이 있는지 확인한다
  • 없으면, 객체 kim를 만들 때 이용한 생성자 Person의, prototype이라는 속성에, sum()이 정의되어 있는지 확인한다

→ 이를 프로토타입 체인이라고 한다
→ 이를 통해 모든 객체는 그 객체의 생성자의 prototype 속성에 정의된 속성과 메서드들을 상속할 수 있다


🔎 javascript-koans

다시 돌아와서


2. AboutInheritance.js

1) function.call()

함수(Function)와 함수의 call() 메소드 참고

var koGreeting = {
  greeting : "안녕",
  name : "홍길동",
  sayHello: function() {
    return this.greeting + ", " + this.name;
  }
};

var enGreeting = {
  greeting: "Hello",
  name: "HongKilDong"
};

console.log(koGreeting.sayHello());
// 안녕, 홍길동

console.log(koGreeting.sayHello.call(enGreeting));
// Hello, HongKilDong
  • 마지막 줄 코드의 의미

    call() 메서드는 koGreeting 객체 안의 sayHello() 메서드가 (koGreeting 객체가 아니라) call() 메서드의 첫 번째 인수로 주어진 enGreeting 객체의 메서드로 동작하도록 해준다


3. AboutApplyingWhatWeHaveLearnt.js

와 어.렵.다.

1) 견과류와 버섯을 못 먹는 사람이 먹을 수 있는 피자 찾기

var products = [
  { name: "Sonoma", ingredients: ["artichoke", "sundried tomatoes", "mushrooms"], containsNuts: false },
  { name: "Pizza Primavera", ingredients: ["roma", "sundried tomatoes", "goats cheese", "rosemary"], containsNuts: false },
  { name: "South Of The Border", ingredients: ["black beans", "jalapenos", "mushrooms"], containsNuts: false },
  { name: "Blue Moon", ingredients: ["blue cheese", "garlic", "walnuts"], containsNuts: true },
  { name: "Taste Of Athens", ingredients: ["spinach", "kalamata olives", "sesame seeds"], containsNuts: true }
];

var productsICanEat = products.filter(function (obj) {
  return (obj.containsNuts === false) && (!obj.ingredients.includes('mushrooms'));
});

console.log(productsICanEat);
// [ { name: "Pizza Primavera", ingredients: ["roma", "sundried tomatoes", "goats cheese", "rosemary"], containsNuts: false } ]
  • filter() 메서드의 인수로 들어오는 함수의 매개변수 obj는 filter() 메서드를 호출한 배열 products의 요소를 의미한다

  • filter() 메서드는, 주어진 함수의 테스트를 통과하는(주어진 함수의 결과가 true인 경우의) 모든 요소들을 모아 새로운 배열로 반환한다

    • (피연산자) && (피연산자)

    • obj.containsNuts === false → 피연산자 1 (true/false)

    • !obj.ingredients.includes('mushrooms') 피연산자 2 (true/false)

    • 피연산자 1과 2가 모두 ture라면, && 연산자에 의해 true가 반환된다

  • 따라서, products.filter(함수)는 피연산자 1과 2가 모두 true가 되는 obj들을 찾아 새로운 배열로 반환한다

2) 3 또는 5의 배수인 1000 미만의 모든 자연수 더하기

// 빈 배열 array 생성
var array = [];

// 배열 array에 1000 미만의 3 또는 5의 배수인 자연수들을 요소로 삽입
for (var i = 1; i < 1000; i++) {
  if (i % 3 === 0 || i % 5 === 0) {
    array.push(i);
  }
}

// 요소들의 값을 다 더하기 위해 reduce() 이용
var answer = array.reduce((prev, curr) => prev + curr);
console.log(answer);
// 233168

3) 모든 피자를 만드는 데 버섯이 몇 개 들어가는가

구하긴 했는데 뭔가 좀 이상한 거 같다

  • products 배열의 각 요소(즉, 각 객체의 ingredients 속성의 값들(즉, ingredients 배열의 요소들))을 뽑아서 새로운 배열로 만듦
    → map 이용

  • 그 만든 배열들을 하나의 배열에 넣기 위해 평탄화 작업
    → flat() 이용

  • mushrooms만 골라냄 → filter() 이용

  • length를 구함

var products = [
  { name: "Sonoma", ingredients: ["artichoke", "sundried tomatoes", "mushrooms"], containsNuts: false },
  { name: "Pizza Primavera", ingredients: ["roma", "sundried tomatoes", "goats cheese", "rosemary"], containsNuts: false },
  { name: "South Of The Border", ingredients: ["black beans", "jalapenos", "mushrooms"], containsNuts: false },
  { name: "Blue Moon", ingredients: ["blue cheese", "garlic", "walnuts"], containsNuts: true },
  { name: "Taste Of Athens", ingredients: ["spinach", "kalamata olives", "sesame seeds"], containsNuts: true }
];

// 1. 정리를 위해 메서드를 쓸 때마다 변수에 할당한 버전

var allIngredients = products.map(function (obj) {
  return obj.ingredients;
});

var flat = allIngredients.flat();

var mushrooms = flat.filter(function (ingredient) {
  return ingredient === 'mushrooms';
});

console.log(mushrooms.length); // 2

// 2. 한 번에 짧게 줄인 버전

var ingredientCount = products.map(function (obj) {
  return obj.ingredients;
})
  .flat()
  .filter(function (ingredient) {
    return ingredient === 'mushrooms';
  }).length;

console.log(ingredientCount); // 2

🙋‍♀️ 질문

원래 사전에 아래 두 줄의 코드가 주어져 있었는데 내가 만들다 보니 이것들이 배제되었다. 사실 이 코드들이 잘 이해가 가지 않는다.

var ingredientCount = { "{ingredient name}": 0 };
console.log(ingredientCount['mushrooms']);

검색해보고 옴

처음부터 mushroom이 들어간 개수를 구하는 게 아니라 어떤 재료라도 몇 개가 들어가는지 구할 수 있도록 코드를 짜야 하는 것이었다.

하지만, 위의 두 코드들을 비롯해 여전히 이해가 안 간다.


✨ 내일 할 것

  1. Number Baseball 구현 시작

좋은 웹페이지 즐겨찾기