Создание объектов в JS без конструкций ООП - PullRequest
0 голосов
/ 08 ноября 2018

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

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

class User{
    name:String;
    age:number;
    function StateCredentials(){
        return "Name:"+this.name+"\r\n"+"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+"\r\n"+"Age:"+this.age;
    }
    x={};
    x.__proto__= User.prototype; 
    User.apply(x,[a]); 
    return x;
});

Вызов

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

Error : Uncaught TypeError: Cannot read property 'StateCredentials' of undefined

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

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

Ответы [ 3 ]

0 голосов
/ 08 ноября 2018

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

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

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

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

console.log(u.StateCredentials());
0 голосов
/ 08 ноября 2018

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

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

user.prototype.StateCredentials = function(){
  return "Name:"+this.name+"\r\n"+"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 не используется в этом сценарии, хотя вы бы иногда видели его в функции конструктора для определенных типов наследования.

0 голосов
/ 08 ноября 2018

Есть несколько проблем с вашим кодом:

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

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

Мне кажется, что разные люди по-разному понимают, что такое "OPP-конструкции" , так что вот несколько примеров.

Нет class синтаксис (функция конструктора + прототип)

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

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

User.prototype.StateCredentials = function() {
 return "Name:"+this.name+"\r\n"+"Age:"+this.age;
}

var u = new User('foo', 42);
console.log(u.StateCredentials());

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


Наши new

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

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

User.prototype.StateCredentials = function() {
  return "Name:" + this.name + "\r\n" + "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), можно также использовать arguments и правильно его нарезать.

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

Нет new

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

var UserPrototype = {
  StateCredentials: function() {
      return "Name:" + this.name + "\r\n" + "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 + "\r\n" + "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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...