Этот вопрос закрыт для ответов, так как повторяет вопрос Зачем нужен конструктор если функция может создать и вернуть объект?

Какая функциональная разница между этими подходами создания объектов в JS?

Мы знаем, что до ES6 у нас не было слова class и объекты создавались вот так:

function User(name,age){
this.name = name;
this.age = age;

this.sayHi = function(){
console.log("My name is " + this.name);
}
}

После прихода сlass, вот так:

class User{
constructor(name,age){
this.name = name;
this.age = age;
}
sayHi(){
console.log("My name is " + this.name)}
}


И если мы создадим экземпляр класса с помощью слова new, мы получим объект. И вся разница будет в том, что во втором случае метод sayHi() пойдет в прототип. Тут вроде все понятно.

let user = new User("Mike",25);

Но что же нам мешает создать не класс, а обычную функцию, которая будет возваращать некий объект:

function User(x,y){
let name = x;
let age = y;

return {
name : name,
age : age,
sayHi: function(){
console.log("My name is " + this.name);
}
}
}


и создавать "экземпляр" без слова new. Мы получим точно такой же объект как и в случае с первым кодом.

let user = User("Mike",25);

У меня собственно 2 вопроса.
1)Какая разница между подходом 1 и 3? И можно ли вообще так писать?
2)Эсли первые 2 сущности принято называть классом, то как называется 3? Если по факту она возвращает объект, но не через слово new.
  • Вопрос задан
  • 475 просмотров
Решения вопроса 3
krdpsr
@krdpsr
loading...
суть в том что это синтаксические сахары

class и new не нужны
можно без них
Ответ написан
VoidVolker
@VoidVolker Куратор тега JavaScript
Dark side eye. А у нас печеньки! А у вас?
Функционально - разницы никакой, т.к. по факту и то и другое реализует одинаковую логику: создание объекта с определенными свойствами. Третий вариант можно назвать функциональным подходом: мы создаем функцию, которая решает свою задачу и не привязываем её к какому-то классу. `new` - просто способ сказать как компилятору, что надо вызвать функцию-конструктор такого-то класса, так и программисту, читающему данный код в будущем, что вот тут мы создаем новый экземпляр такого-то класса. Так же и, например, {} просто упрощенная запись new Object() для создания объекта.
Ответ написан
Xuxicheta
@Xuxicheta
инженер
допустим User это функция-конструктор, или класс.
user = new User()

будет создан объект, у которого есть свойство __proto__ в котором лежит объект, состоящий из одного свойства constructor, которая и есть ваша функция User. (Ну типа такой { constuctor: User }. Если писать через class то мы конструктор явно прям зададим. )
Этот же объект лежит по адресу User.prototype, т.е.
user.__proto__ === User.prototype
Этот объект создается для любой объявленной функции (вообще не обязан, но в V8 вроде так), и например User.prototype.constructor === User

Что такое метод класса, это функция по адресу User.prototype.sayHi (оно же лежит в user.__proto__.sayHi)
Потом, когда мы пишем user.sayHi js проходит по цепочке из свойств __proto__ и ищет там эту функцию, вызывает ее и передает в качестве контекста (this) наш объект user.

А теперь посмотрим разницу с вашим
function User(x,y){
let name = x;
let age = y;

return {
name : name,
age : age,
sayHi: function(){
console.log("My name is " + this.name);
}
}
}


тут все поля и функции лежат в одном объекте, который имеет только дефолтный __proto__ Object.prototype, автоматически присваиваемый при создании объекта через объектный литерал.
При вызове функции несколько раз будут созданы несколько никак не связанных объекта. Прототип у них Object, это единственное что их роднит. Функции будут созданы каждый раз заново.
user1.sayHi !== user2.sayHi
Оператор instanceof не найдет у них общего предка User.

Вот в этом и разница. Можно ли так писать? Можно, только зачем?
Как назвать? Ну допустим функция-фабрика объектов. (не путатьс классом-фабрикой и со статическим фабричным методом, там создаются инстансы классов).

Найдёте теперь сами разницу в ваших примерах 1 и 2?
А так же почему в примере 1 new User() и просто User() дадут совершенно разный результат? И как сделать чтоб было одинаково?
Ответ написан
Ваш ответ на вопрос

Вопрос закрыт для ответов и комментариев

Потому что уже есть похожий вопрос.
Похожие вопросы