допустим 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() дадут совершенно разный результат? И как сделать чтоб было одинаково?