const productList = {
products: [
{
title: "A Pillow",
imageUrl:
"https://i.namu.wiki/i/BkYYZlR90zQhgRZxXY1eDgRGO9RwOq_vMk1LOO2FdMxxHjcGml5-B8R10Y5RalGf9YIXV6YLAxR0M8DO-8b-dw.webp",
price: 19.99,
description: "A soft pillow!",
},
{
title: "A Carpet",
imageUrl:
"https://post-phinf.pstatic.net/MjAyMzExMDFfMjM0/MDAxNjk4ODE2NzM1OTc0.y3BvOwThLelXn8FB4Q8NwYt-L0XskUey-PY8YvwPemgg.SUk02UQLxFxju312e8oIevXl3eYibZsEpKUPkPM6uq4g.JPEG/06_레전드_페스티벌_시작.jpg?type=w800_q75",
price: 89.99,
description: "A carpet which you might like.",
},
],
render() {
const renderHook = document.getElementById("app");
const prodList = document.createElement("ul");
prodList.className = "product-list";
for (const prod of this.products) {
const prodEl = document.createElement("li");
prodEl.className = "product-item";
prodEl.innerHTML = `
<div>
<img src="${prod.imageUrl}" alt="${prod.title}" >
<div class="product-item__content">
<h2>${prod.title}</h2>
<h3>\$${prod.price}</h3>
<p>${prod.description}</p>
<button>Add to Cart</button>
</div>
</div>
`;
prodList.append(prodEl);
}
renderHook.append(prodList);
},
};
productList.render();
Classes & Instances
Objects
Classes
클래스 사용하기
new 키워드 : JavaScript가 인식하는 키워드로서 클래스를 기반으로 한 함수의 실행과 함께 인식된다. (진짜 함수는 아니지만) 새로운 객체를 생성.class Product {
constructor(title, image, desc, price) {
this.title = title; // this = 클래스
this.imageUrl = image;
this.description = desc;
this.price = price;
} // 생성자에 넣은 값으로 속성의 값이 초기화.
}
const productList = {
products: [
new Product(
"A Pillow",
"https://i.namu.wiki/i/BkYYZlR90zQhgRZxXY1eDgRGO9RwOq_vMk1LOO2FdMxxHjcGml5-B8R10Y5RalGf9YIXV6YLAxR0M8DO-8b-dw.webp",
"A soft pillow!",
19.99
),
new Product(
"A Carpet",
"https://post-phinf.pstatic.net/MjAyMzExMDFfMjM0/MDAxNjk4ODE2NzM1OTc0.y3BvOwThLelXn8FB4Q8NwYt-L0XskUey-PY8YvwPemgg.SUk02UQLxFxju312e8oIevXl3eYibZsEpKUPkPM6uq4g.JPEG/06_레전드_페스티벌_시작.jpg?type=w800_q75",
"A carpet which you might like.",
89.99
),
],
render() {
const renderHook = document.getElementById("app");
const prodList = document.createElement("ul");
prodList.className = "product-list";
for (const prod of this.products) {
const prodEl = document.createElement("li");
prodEl.className = "product-item";
prodEl.innerHTML = `
<div>
<img src="${prod.imageUrl}" alt="${prod.title}" >
<div class="product-item__content">
<h2>${prod.title}</h2>
<h3>\$${prod.price}</h3>
<p>${prod.description}</p>
<button>Add to Cart</button>
</div>
</div>
`;
prodList.append(prodEl);
}
renderHook.append(prodList);
},
};
productList.render();
class Product {
category = "DEFAULT"; // (Public) Class Field
constructor(title) {
this.title = title; // (Public) Class Property
}
printInfo() {
console.log(this.title, this.category);
}
}
class Product {
constructor(title, image, desc, price) {
this.title = title; // this = 클래스
this.imageUrl = image;
this.description = desc;
this.price = price;
} // 생성자에 넣은 값으로 속성의 값이 초기화.
}
class ProductItem {
constructor(product) {
this.product = product;
}
render() {
const prodEl = document.createElement("li");
prodEl.className = "product-item";
prodEl.innerHTML = `
<div>
<img src="${this.product.imageUrl}" alt="${this.product.title}" >
<div class="product-item__content">
<h2>${this.product.title}</h2>
<h3>\$${this.product.price}</h3>
<p>${this.product.description}</p>
<button>Add to Cart</button>
</div>
</div>
`;
return prodEl;
}
}
class ProductList {
products = [
new Product(
"A Pillow",
"https://i.namu.wiki/i/BkYYZlR90zQhgRZxXY1eDgRGO9RwOq_vMk1LOO2FdMxxHjcGml5-B8R10Y5RalGf9YIXV6YLAxR0M8DO-8b-dw.webp",
"A soft pillow!",
19.99
),
new Product(
"A Carpet",
"https://post-phinf.pstatic.net/MjAyMzExMDFfMjM0/MDAxNjk4ODE2NzM1OTc0.y3BvOwThLelXn8FB4Q8NwYt-L0XskUey-PY8YvwPemgg.SUk02UQLxFxju312e8oIevXl3eYibZsEpKUPkPM6uq4g.JPEG/06_레전드_페스티벌_시작.jpg?type=w800_q75",
"A carpet which you might like.",
89.99
),
];
constructor() {}
render() {
const renderHook = document.getElementById("app");
const prodList = document.createElement("ul");
prodList.className = "product-list";
for (const prod of this.products) {
const product = new ProductItem(prod);
const prodEl = product.render();
prodList.append(prodEl);
}
renderHook.append(prodList);
}
}
const productList = new ProductList();
productList.render();
Product 클래스 : 제품에 대한 기본 요소 정보를 담는 클래스ProductItem 클래스 : 화면에 제품 요소를 렌더링을 하기 위한 클래스ProductList 클래스 : Product 클래스를 이용하여 제품 정보를 입력 → ProductItem 클래스를 이용해서 화면 렌더링class ProductItem {
constructor(product) {
this.product = product;
}
addToCart() {
console.log("Adding product to cart...");
console.log(this.product);
}
render() {
const prodEl = document.createElement("li");
prodEl.className = "product-item";
prodEl.innerHTML = `
<div>
<img src="${this.product.imageUrl}" alt="${this.product.title}" >
<div class="product-item__content">
<h2>${this.product.title}</h2>
<h3>\$${this.product.price}</h3>
<p>${this.product.description}</p>
<button>Add to Cart</button>
</div>
</div>
`;
const addCartButton = prodEl.querySelector("button"); // 단일 상품을 생성하는 단일 클래스이기 때문에 해당 코드를 통해서 정확한 버튼에 엑세스 가능
addCartButton.addEventListener("click", this.addToCart.bind(this)); // bind(this)에서 this는 전체 객체
return prodEl;
}
}
class Product {
constructor(title, image, desc, price) {
this.title = title;
this.imageUrl = image;
this.description = desc;
this.price = price;
}
}
class ProductItem {
constructor(product) {
this.product = product;
}
addToCart() {
console.log("Adding product to cart...");
console.log(this.product);
}
render() {
const prodEl = document.createElement("li");
prodEl.className = "product-item";
prodEl.innerHTML = `
<div>
<img src="${this.product.imageUrl}" alt="${this.product.title}" >
<div class="product-item__content">
<h2>${this.product.title}</h2>
<h3>\$${this.product.price}</h3>
<p>${this.product.description}</p>
<button>Add to Cart</button>
</div>
</div>
`;
const addCartButton = prodEl.querySelector("button");
addCartButton.addEventListener("click", this.addToCart.bind(this));
return prodEl;
}
}
// 추가
class ShoppingCart {
items = [];
render() {
const cartEl = document.createElement("section");
cartEl.innerHTML = `
<h2>Total: \$${0}</h2>
<button>Order Now!</button>
`;
cartEl.className = "cart";
return cartEl;
}
}
class ProductList {
products = [
new Product(
"A Pillow",
"https://i.namu.wiki/i/BkYYZlR90zQhgRZxXY1eDgRGO9RwOq_vMk1LOO2FdMxxHjcGml5-B8R10Y5RalGf9YIXV6YLAxR0M8DO-8b-dw.webp",
"A soft pillow!",
19.99
),
new Product(
"A Carpet",
"https://post-phinf.pstatic.net/MjAyMzExMDFfMjM0/MDAxNjk4ODE2NzM1OTc0.y3BvOwThLelXn8FB4Q8NwYt-L0XskUey-PY8YvwPemgg.SUk02UQLxFxju312e8oIevXl3eYibZsEpKUPkPM6uq4g.JPEG/06_레전드_페스티벌_시작.jpg?type=w800_q75",
"A carpet which you might like.",
89.99
),
];
constructor() {}
// 변경
render() {
const prodList = document.createElement("ul");
prodList.className = "product-list";
for (const prod of this.products) {
const product = new ProductItem(prod);
const prodEl = product.render();
prodList.append(prodEl);
}
return prodList; // prodList를 반환
}
}
// 추가 : 전체적인 화면을 렌더링하는 역할
class Shop {
render() {
const renderHook = document.getElementById("app");
const cart = new ShoppingCart();
const cartEl = cart.render();
const productList = new ProductList();
const prodListEl = productList.render();
renderHook.append(cartEl);
renderHook.append(prodListEl);
}
}
const shop = new Shop();
shop.render();
Static Field / Property / Method
static 키워드가 붙는다.Instance Field / Property / Method
static 키워드 없이 정의.class Product {
constructor(title, image, desc, price) {
this.title = title; // this = 클래스
this.imageUrl = image;
this.description = desc;
this.price = price;
} // 생성자에 넣은 값으로 속성의 값이 초기화.
}
class ProductItem {
constructor(product) {
this.product = product;
}
addToCart() {
App.addProductToCart(this.product);
}
render() {
const prodEl = document.createElement("li");
prodEl.className = "product-item";
prodEl.innerHTML = `
<div>
<img src="${this.product.imageUrl}" alt="${this.product.title}" >
<div class="product-item__content">
<h2>${this.product.title}</h2>
<h3>\$${this.product.price}</h3>
<p>${this.product.description}</p>
<button>Add to Cart</button>
</div>
</div>
`;
const addCartButton = prodEl.querySelector("button"); // 단일 상품을 생성하는 단일 클래스이기 때문에 해당 코드를 통해서 정확한 버튼에 엑세스 가능
addCartButton.addEventListener("click", this.addToCart.bind(this)); // bind(this)에서 this는 전체 객체
return prodEl;
}
}
class ShoppingCart {
items = [];
addProduct(product) {
this.items.push(product);
this.totalOutput.innerHTML = `<h2>Total: \$${1}</h2>`;
}
render() {
const cartEl = document.createElement("section");
cartEl.innerHTML = `
<h2>Total: \$${0}</h2>
<button>Order Now!</button>
`;
cartEl.className = "cart";
this.totalOutput = cartEl.querySelector("h2"); // 객체에 새 프로퍼티를 언제든 동적으로 추가 가능
return cartEl;
}
constructor() {}
}
class ProductList {
products = [
new Product(
"A Pillow",
"https://i.namu.wiki/i/BkYYZlR90zQhgRZxXY1eDgRGO9RwOq_vMk1LOO2FdMxxHjcGml5-B8R10Y5RalGf9YIXV6YLAxR0M8DO-8b-dw.webp",
"A soft pillow!",
19.99
),
new Product(
"A Carpet",
"https://post-phinf.pstatic.net/MjAyMzExMDFfMjM0/MDAxNjk4ODE2NzM1OTc0.y3BvOwThLelXn8FB4Q8NwYt-L0XskUey-PY8YvwPemgg.SUk02UQLxFxju312e8oIevXl3eYibZsEpKUPkPM6uq4g.JPEG/06_레전드_페스티벌_시작.jpg?type=w800_q75",
"A carpet which you might like.",
89.99
),
];
constructor() {}
render() {
const prodList = document.createElement("ul");
prodList.className = "product-list";
for (const prod of this.products) {
const product = new ProductItem(prod);
const prodEl = product.render();
prodList.append(prodEl);
}
return prodList;
}
}
class Shop {
render() {
const renderHook = document.getElementById("app");
this.cart = new ShoppingCart();
const cartEl = this.cart.render();
const productList = new ProductList();
const prodListEl = productList.render();
renderHook.append(cartEl);
renderHook.append(prodListEl);
}
}
class App {
static cart;
static init() {
const shop = new Shop();
shop.render();
this.cart = shop.cart;
// this.cart는 Shop 클래스의 render 함수 안에서 인스턴스화가 되어있기 때문에 호출되는 순서는 shop.render() -> this.cart = shop.cart();가 된다.
}
static addProductToCart(product) {
this.cart.addProduct(product); // this.cart 는 ShoppingCart 클래스에 근거한 인스턴스를 나타낸다.
}
}
App.init(); // init 메서드를 클래스에 바로 실행. 클래스에서 바로 작동