В Авито тысячи объявлений. Каждое — объект с полями: название, цена, город, дата. Если описывать каждый объект вручную { title: ..., price: ..., city: ... } — это дублирование кода и риск ошибиться в названии поля. Конструктор — это фабрика: описываешь структуру один раз, создаёшь сколько угодно одинаково устроенных объектов.
По соглашению конструкторы называются с заглавной буквы — чтобы отличать от обычных функций:
function Product(name, price, category) {
// При вызове через new:
// 1. Создаётся пустой объект {}
// 2. this = этот объект
this.name = name
this.price = price
this.category = category
this.inStock = true
// 3. return this (автоматически)
}
const laptop = new Product('Ноутбук', 75000, 'tech')
const mouse = new Product('Мышь', 1500, 'tech')
console.log(laptop.name) // 'Ноутбук'
console.log(mouse.price) // 1500function User(name) {
// Шаг 1: движок делает this = {}
// Шаг 2: выполняется код функции
this.name = name
this.createdAt = new Date().toISOString()
// Шаг 3: движок делает return this
}Если вызвать без new — this будет undefined (в strict mode) или глобальным объектом:
const u = User('Иван') // забыли new!
console.log(u) // undefinedfunction BankAccount(owner, initialBalance) {
this.owner = owner
this.balance = initialBalance
this.deposit = function(amount) {
this.balance += amount
return this // для цепочки
}
this.getBalance = function() {
return `${this.owner}: ${this.balance} ₽`
}
}
const acc = new BankAccount('Алексей', 10000)
acc.deposit(5000)
console.log(acc.getBalance()) // 'Алексей: 15000 ₽'> Примечание: методы в конструкторе создаются заново для каждого экземпляра. Эффективнее добавлять их через прототип или использовать классы.
console.log(laptop instanceof Product) // true
console.log(laptop instanceof Array) // falseОшибка 1: вызов без new
// Сломано:
function User(name) { this.name = name }
const u = User('Иван') // this = window или undefined!
console.log(u) // undefined
// Исправлено:
const u = new User('Иван')Ошибка 2: явный return объекта из конструктора
// Неожиданное поведение:
function User(name) {
this.name = name
return { surprise: true } // new вернёт этот объект, а не this!
}
const u = new User('Иван')
console.log(u.name) // undefined — вернулся { surprise: true }
// Правило: если в конструкторе нужен return — возвращай только примитивы
// (они игнорируются, new вернёт this)Ошибка 3: забыть сохранить значение
// Сломано:
function Product(name, price) {
name = name // присваивает локальной переменной, не this!
price = price
}
// Исправлено:
function Product(name, price) {
this.name = name
this.price = price
}new Error(), new Map(), new Promise()new XMLHttpRequest(), new FormData(), new URL()Конструктор Listing — объявления на доске объявлений
function Listing(title, price, city, category) {
this.id = Math.random().toString(36).slice(2, 8)
this.title = title
this.price = price
this.city = city
this.category = category
this.createdAt = new Date().toISOString()
this.views = 0
this.view = function() {
this.views++
return this
}
this.applyDiscount = function(percent) {
return new Listing(
this.title + ' (скидка ' + percent + '%)',
Math.round(this.price * (1 - percent / 100)),
this.city,
this.category
)
}
this.toString = function() {
return `[${this.category}] ${this.title} — ${this.price} ₽ (${this.city})`
}
}
const bike = new Listing('Велосипед Trek', 25000, 'Москва', 'sport')
const laptop = new Listing('Ноутбук Lenovo', 45000, 'СПб', 'tech')
const desk = new Listing('Стол IKEA', 8000, 'Москва', 'furniture')
bike.view().view().view()
console.log(bike.views) // 3
console.log(laptop.toString()) // '[tech] Ноутбук Lenovo — 45000 ₽ (СПб)'
const saleLaptop = laptop.applyDiscount(15)
console.log(saleLaptop.price) // 38250
console.log(laptop.price) // 45000 — оригинал не изменился
const listings = [bike, laptop, desk]
const moscow = listings.filter(l => l.city === 'Москва')
console.log(moscow.map(l => l.title))
// ['Велосипед Trek', 'Стол IKEA']
console.log(bike instanceof Listing) // trueВ Авито тысячи объявлений. Каждое — объект с полями: название, цена, город, дата. Если описывать каждый объект вручную { title: ..., price: ..., city: ... } — это дублирование кода и риск ошибиться в названии поля. Конструктор — это фабрика: описываешь структуру один раз, создаёшь сколько угодно одинаково устроенных объектов.
По соглашению конструкторы называются с заглавной буквы — чтобы отличать от обычных функций:
function Product(name, price, category) {
// При вызове через new:
// 1. Создаётся пустой объект {}
// 2. this = этот объект
this.name = name
this.price = price
this.category = category
this.inStock = true
// 3. return this (автоматически)
}
const laptop = new Product('Ноутбук', 75000, 'tech')
const mouse = new Product('Мышь', 1500, 'tech')
console.log(laptop.name) // 'Ноутбук'
console.log(mouse.price) // 1500function User(name) {
// Шаг 1: движок делает this = {}
// Шаг 2: выполняется код функции
this.name = name
this.createdAt = new Date().toISOString()
// Шаг 3: движок делает return this
}Если вызвать без new — this будет undefined (в strict mode) или глобальным объектом:
const u = User('Иван') // забыли new!
console.log(u) // undefinedfunction BankAccount(owner, initialBalance) {
this.owner = owner
this.balance = initialBalance
this.deposit = function(amount) {
this.balance += amount
return this // для цепочки
}
this.getBalance = function() {
return `${this.owner}: ${this.balance} ₽`
}
}
const acc = new BankAccount('Алексей', 10000)
acc.deposit(5000)
console.log(acc.getBalance()) // 'Алексей: 15000 ₽'> Примечание: методы в конструкторе создаются заново для каждого экземпляра. Эффективнее добавлять их через прототип или использовать классы.
console.log(laptop instanceof Product) // true
console.log(laptop instanceof Array) // falseОшибка 1: вызов без new
// Сломано:
function User(name) { this.name = name }
const u = User('Иван') // this = window или undefined!
console.log(u) // undefined
// Исправлено:
const u = new User('Иван')Ошибка 2: явный return объекта из конструктора
// Неожиданное поведение:
function User(name) {
this.name = name
return { surprise: true } // new вернёт этот объект, а не this!
}
const u = new User('Иван')
console.log(u.name) // undefined — вернулся { surprise: true }
// Правило: если в конструкторе нужен return — возвращай только примитивы
// (они игнорируются, new вернёт this)Ошибка 3: забыть сохранить значение
// Сломано:
function Product(name, price) {
name = name // присваивает локальной переменной, не this!
price = price
}
// Исправлено:
function Product(name, price) {
this.name = name
this.price = price
}new Error(), new Map(), new Promise()new XMLHttpRequest(), new FormData(), new URL()Конструктор Listing — объявления на доске объявлений
function Listing(title, price, city, category) {
this.id = Math.random().toString(36).slice(2, 8)
this.title = title
this.price = price
this.city = city
this.category = category
this.createdAt = new Date().toISOString()
this.views = 0
this.view = function() {
this.views++
return this
}
this.applyDiscount = function(percent) {
return new Listing(
this.title + ' (скидка ' + percent + '%)',
Math.round(this.price * (1 - percent / 100)),
this.city,
this.category
)
}
this.toString = function() {
return `[${this.category}] ${this.title} — ${this.price} ₽ (${this.city})`
}
}
const bike = new Listing('Велосипед Trek', 25000, 'Москва', 'sport')
const laptop = new Listing('Ноутбук Lenovo', 45000, 'СПб', 'tech')
const desk = new Listing('Стол IKEA', 8000, 'Москва', 'furniture')
bike.view().view().view()
console.log(bike.views) // 3
console.log(laptop.toString()) // '[tech] Ноутбук Lenovo — 45000 ₽ (СПб)'
const saleLaptop = laptop.applyDiscount(15)
console.log(saleLaptop.price) // 38250
console.log(laptop.price) // 45000 — оригинал не изменился
const listings = [bike, laptop, desk]
const moscow = listings.filter(l => l.city === 'Москва')
console.log(moscow.map(l => l.title))
// ['Велосипед Trek', 'Стол IKEA']
console.log(bike instanceof Listing) // trueНапиши конструктор Message(from, text) для мессенджера. Каждое сообщение имеет: id (случайный), from, text, timestamp (текущее время ISO), isRead: false. Добавь методы: markAsRead() — помечает прочитанным и возвращает this, reply(text) — создаёт и возвращает новое сообщение от 'Bot' с указанным текстом, toString() — возвращает строку вида "[от кого] текст".
id: Math.random().toString(36).slice(2, 8). timestamp: new Date().toISOString(). reply возвращает new Message("Bot", replyText). toString: `[${this.from}] ${this.text}`