Создание объектов в JS без конструкций ООП

Привет, я пытаюсь понять, как объекты создаются в JS. Поэтому я пытаюсь создать следующий класс с простым JS. (Я знаю, что не могу укрепить типы), просто разместил их там как ссылку.

Желаемое поведение

class User{
    name:String;
    age:number;
    function StateCredentials(){
        return "Name:"+this.name+"
"+"Age:"+this.age;
    }
}

Я не понял порядок, в котором вы прикрепляете прототип к текущему объекту и когда вы вызываете его apply Также, где должен быть установлен метод экземпляра.

Текущая реализация

User=(function(age,name){
    function User(name,age){
        this.name=name;
        this.age=age;
        this.credentials=SetCredentials;
    }
    function StateCredentials(){
        return "Name:"+this.name+"
"+"Age:"+this.age;
    }
    x={};
    x.__proto__= User.prototype; 
    User.apply(x,[a]); 
    return x;
});

Звоните :

function createObject(){
    u=User(3,3);
    u.StateCredentials();
}

Ошибка : Uncaught TypeError: Cannot read property 'StateCredentials' of undefined

В качестве последней заметки я видел реализацию, в которой анонимный метод является триггером, который включает логику конструктора.

(function(){...})(arugments);

Всего 3 ответа


Есть пара проблем с кодом:

  • Функция User ничего не возвращает. Вот почему u не undefined и вы получаете эту ошибку. Вам нужно добавить return x;
  • Даже при этом вызов u.StateCredentials(); будет терпеть неудачу, потому что вы никогда не StateCredentials свойство StateCredentials на x . Ближайшим вам является создание credentials свойств, поэтому вы можете сделать u.credentials() .
  • Вы все равно ничего не увидите, потому что вы ничего не делаете с возвращаемым значением. Вы можете сделать console.log(u.credentials()) .

В целом я не совсем уверен, чего вы пытаетесь достичь. Игнорируя, что ваш пример класса синтаксически неверен, class es являются «обычным JavaScript». Синтаксис официально является частью языка с 2015 года.

Я чувствую, что разные люди понимают, что такое «OPP-конструкции» , так что вот несколько примеров.

Синтаксис class (конструктор + прототип)

class - это более или менее просто синтаксический сахар. Под капотом мы имеем дело с обычными конструкторскими функциями. Поэтому, если вы спрашиваете, как выглядит эквивалентный пример синтаксиса перед классом, это будет примерно так:

 function User(name, age) { this.name = name; this.age = age; } User.prototype.StateCredentials = function() { return "Name:"+this.name+"
"+"Age:"+this.age; } var u = new User('foo', 42); console.log(u.StateCredentials()); 

Нет необходимости фактически создавать объект самостоятельно, потому что это делает это для вас.


Наш собственный new

Если вы спрашиваете, как в основном реализовать new самостоятельно, тогда это будет примерно так:

 function User(name, age) { this.name = name; this.age = age; } User.prototype.StateCredentials = function() { return "Name:" + this.name + "
" + "Age:" + this.age; } function newNew(constructor, ...args) { var instance = Object.create(constructor.prototype); var result = constructor.apply(instance, args); if (result && typeof result === 'object') { return result; } return instance; } var u = newNew(User, 'foo', 42); console.log(u.StateCredentials()); 

Примечание. Я использую параметры ...args ( ...args ) для неявно здесь, можно также использовать arguments и отрезать его правильно.

  • Object.create(...) выполняет «магическую» часть создания нового объекта с определенным значением, так как это protoype.
  • constructor.apply(...) просто вызывает конструктор с новым объектом, установленным как его значение.
  • Затем мы возвращаем возвращаемое значение конструктора, если это объект или объект, который мы только что создали.

Нет new

Если вы спрашиваете, как будет выглядеть эквивалент без new , конструкторских функций и this , тогда это будет примерно так:

 var UserPrototype = { StateCredentials: function() { return "Name:" + this.name + "
" + "Age:" + this.age; }, }; function makeUser(name, age) { var instance = Object.create(UserPrototype); instance.name = name; instance.age = age; return instance; } var u = makeUser('foo', 42); console.log(u.StateCredentials()); 

Нам все еще нужен Object.create для создания нового объекта с определенным значением в качестве его прототипа.


Нет прототипов

Если вы фактически не хотите использовать прототипы, вы можете объединить объекты с помощью var instance = Object.assign({}, UserProtoype); вместо этого или определять и назначать методы индивидуально

 function StateCredentials() { return "Name:" + this.name + "
" + "Age:" + this.age; } function makeUser(name, age) { return { name: name, age: age, StateCredentials: StateCredentials, }; } var u = makeUser('foo', 42); console.log(u.StateCredentials()); 

И конечно, StateCredentials можно определить внутри makeUser . Это шаг оптимизации, так что мы создаем новую копию этой функции каждый раз, makeUser вызывается makeUser .


Или вы можете использовать класс для новых браузеров

class User {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }

  StateCredentials() {
    return "Name:"+this.name+"
"+"Age:"+this.age;
  }
}

let u = new User('name', 31);

console.log(u.StateCredentials());

Вы делаете это намного сложнее, чем это должно быть:

function user(age,name){
  this.name=name;
  this.age=age;
}

user.prototype.StateCredentials = function(){
  return "Name:"+this.name+"
"+"Age:"+this.age;
}

var u = new user(12, "Little Billy");
console.log(u.StateCredentials());
var v = new user(11, "Little Suzy");
console.log(v.StateCredentials());

Прототип связан с new ключевым словом. apply не используется в этом сценарии, хотя иногда вы можете увидеть его в функции-конструкторе для определенных типов наследования.


Есть идеи?

10000