Reputation: 9370
Hello i am trying to understand how objects are created in JS.Therefore i am trying to create the following class with plain JS.(I know i can't reinforce types) ,just placed them there as a reference.
Desired behaviour
class User{
name:String;
age:number;
function StateCredentials(){
return "Name:"+this.name+"\r\n"+"Age:"+this.age;
}
}
I did not understand the order in which you attach the the prototype to the current object and when do you call apply
on it.Also where should the instance method be placed.
Current Implementation
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;
});
Call:
function createObject(){
u=User(3,3);
u.StateCredentials();
}
Error:
Uncaught TypeError: Cannot read property 'StateCredentials' of undefined
As a last note i have seen an implementation where an anonymous method is the trigger that encloses the constructor logic.
(function(){...})(arugments);
Upvotes: 0
Views: 160
Reputation: 817000
There are a couple of issues with your code:
User
function doesn't return anything. That's why u
is undefined
and you get that error. You'd have to add return x;
u.StateCredentials();
would fail because you are never creating a property StateCredentials
on x
. The closest you are ding is creating the property credentials
, so you could do u.credentials()
.console.log(u.credentials())
.Overall I'm not quite sure what you are trying to achieve. Ignoring that your class example is syntactically incorrect, class
es are "plain JavaScript". The syntax is officially part of the language since 2015.
I feel like different people have a different understanding of what "OPP constructs" really are, so here are a couple of examples.
No class
syntax (constructor function + prototype)
class
is more or less just syntactic sugar. Under the hood we deal with normal constructor functions. So if you are asking how the equivalent pre-class syntax example looks like, it would be something like this:
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());
There is no need to actually instantiate the object yourself because new
does that for you.
Our own new
If you are asking how to basically implement new
yourself, then it would be something like this:
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());
Note: I'm using rest parameters (...args
) for implicitly here, one could as well use arguments
and slice it correctly.
Object.create(...)
does the "magical" part of creating a new object with a specific value as it's protoype.constructor.apply(...)
simply calls the constructor with the new object set as its this
value.No new
If you are asking how the equivalent would look like without new
, constructor functions and this
, then it would be something like 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());
We still need Object.create
to create a new object with a specific value as its prototype.
No prototypes
If you don't actually want to use prototypes, you can merge the objects using var instance = Object.assign({}, UserProtoype);
instead or define and assign methods individually
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());
And sure, StateCredentials
could be defined inside makeUser
. This is an optimization step so that we creating a new copy of that function every time makeUser
is called.
Upvotes: 1
Reputation: 574
You're making this a lot more complicated than it has to be:
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());
Prototype is attached with the new
keyword. apply
isn't used in this scenario, though you would occasionally see it in a constructor function for certain types of inheritance.
Upvotes: 0
Reputation: 841
Or you could use class for newer browsers
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());
Upvotes: 1