0

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);
4
  • "i am trying to understand how objects are created in JS." To be clear: There are multiple ways to create objects, using new Constructor() is just one of them. The simplest is to use an object literal, {...}. Are you basically asking how new works? Commented Nov 8, 2018 at 7:38
  • "without OOP constructs" What are OOP constructors for you? I feel like people have a different understand of what OOP means. JavaScript is all about objects. Commented Nov 8, 2018 at 7:40
  • I was referring to how would you create an object if you would not have constructor syntatic sugar. I was expecting to be something similar to how you would do it in a language like Clang.And i was curious on how and where you attach the class method "pointers". Commented Nov 8, 2018 at 7:43
  • A constructor is really just a function that initializes an object. As I said, the simplest way to create an object is to use an object literal. Any function that creates and returns an object would be a constructor then. "And i was curious on how you and where you attach the method "pointers"." Assuming the methods/functions are predefined, all you need to do is obj.method = method;. Commented Nov 8, 2018 at 7:46

3 Answers 3

1

There are a couple of issues with your code:

  • The User function doesn't return anything. That's why u is undefined and you get that error. You'd have to add return x;
  • Even with that, the call 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().
  • You still wouldn't see anything though because you are not doing anything with the return value. You could do console.log(u.credentials()).

Overall I'm not quite sure what you are trying to achieve. Ignoring that your class example is syntactically incorrect, classes 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.
  • Then we either return the return value of the constructor if it is an object, or the object we just created.

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.

Sign up to request clarification or add additional context in comments.

5 Comments

What is the difference between setting the SetCredentials to a this field inside the constructor (as i did) or setting it by attaching to the User.prototype property? Why should instance methods be set as prototype fields and fields not ?
See Use of 'prototype' vs. 'this' in JavaScript? for a comprehensive answer on that one.
The last part of your answer is what really solved my confusion.And how would you enclose all that logic inside one method?To behave "like a constructor".Can you place it all inside a wrapper ?
makeUser is basically a constructor... not sure what else you want. That UserPrototype is defined inside the function? Then we would create a new copy of the object and function every time makeUser is called, which works but is unnecessary.
I added another example that doesn't use prototypes though there isn't a huge difference.
1

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());

2 Comments

Thank you for your suggestions.However i wanted to know how it translates at the lowest level.
@BercoviciAdrian: "However i wanted to know how it translates at the lowest level." You essentially want to know how new works then. See the second example in my answer.
0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.