Есть несколько проблем с вашим кодом:
- Функция
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
.