2

I know that, we can create the new instance of functions by the following approach. But my question is there any other way to achieve the same?

var Person = function (firstName) {
  this.firstName = firstName;
  console.log('Person instantiated');
};

var person1 = new Person('Alice');
var person2 = new Person('Bob');

// Show the firstName properties of the objects
console.log('person1 is ' + person1.firstName); // logs "person1 is Alice"
console.log('person2 is ' + person2.firstName); // logs "person2 is Bob"

Since, some time in case of new declaration fails, i am not getting the error too..

Especially, in javascript oops concept requires the different approach.

Some times, I am confusing without even calling the new key words it all works fine.. what is the different between using the new keyword and without using that?

example :

var setColor = function (color) {
   return color;
}

var x = setColor('red');
var y = setColor('blue');

console.log(y);
console.log(x);
3
  • What kind of code do you have that's causing new operator to fail? Could/should this question be changed to ask about your specific case and why new is failing, rather than looking for alternative ways to instantiate an object instance? Commented Mar 2, 2015 at 5:13
  • @JoelCox - i updated my question. I agree we required the new keyword, but even omitting that i did not see any difference. Commented Mar 2, 2015 at 5:16
  • Note that when called with new, a function must return an object. In the above, you are passing a primitive string, so the constructor is returning the new object referenced by this, not the string. Commented Mar 2, 2015 at 5:35

4 Answers 4

3

The new [Function] keyword does many things, but the main things it does are:

  • Creates a new object
  • Uses [Function]'s prototype as the parent prototype for the new object
  • Executes the contents of [Function], using this as a reference to the new object

If you call such a function without new, the this reference will be determined the way it would usually be determined when calling a function, and quite often this would be the global object.

One thing you can do to help catch these mistakes more easily is to use strict mode:

"use strict";

var Person = function (firstName) {
  this.firstName = firstName;
  console.log('Person instantiated');
};

var person1 = Person('Alice');

If the above code were executed, this would be null instead of the global object, and you would get an error right away instead of having the properties assigned to the global object (and having hard-to-catch bugs).

A way to avoid these kinds of mistakes with new altogether is to simply have the function return a new object instead of being a constructor:

var person = function (firstName) {
  console.log('person instantiated');
  return {
      firstName: firstName
  };
};

var person1 = person('Alice');
var person2 = person('Bob');

If you do this, it doesn't matter whether you use new or not, because the function doesn't use this.

Edit There was a question below about prototypes. If you are unfamiliar with prototypes, this is a feature that allows you to specify properties and methods that will be shared between all instances of an object:

"use strict";

var Person = function (firstName) {
  this.firstName = firstName;
  console.log('Person instantiated');
};

Person.prototype.getMyName = function () {
    return this.firstName;
};

var person1 = new Person('Alice');
console.log(person1.getMyName());

If you do this, then all instances created with new Person() will share the getMyName method.

The new-less option I detailed later on does not provide this automatic prototype extension, but there are alternatives:

Option 1 - don't use a prototype:

var person = function (firstName) {
  console.log('person instantiated');
  return {
      firstName: firstName,
      getMyName: function () {
          return this.firstName;
      }
  };
};

Option 2 - Use Object.create() to extend the prototype:

var person = function (firstName) {
  console.log('person instantiated');
  var person = Object.create(person.prototype);
  person.firstName = firstName;

  return person;
};

Option 3 - Use Object.assign() method to copy the contents of the prototype to a new object:

var person = function (firstName) {
  console.log('person instantiated');

  return Object.assign({
      firstName: firstName
  }, person.prototype);
};
Sign up to request clarification or add additional context in comments.

5 Comments

But the returned object doesn't inherit from the constructor's prototype, it will inherit only from Object.prototype.
yes, Exactly I am getting confuse here.. can you tell me what is wrong with my approach and what it mean inherit from the constructor's prototype by simple example..?
But please do not capitalize the name of a function unless you intend it to be called with the new keyword.
@RobG Yes, certainly that's a big difference, but some people are of the opinion that using new is bad, and there are certainly alternatives, but I will make a note of this in my answer.
@3gwebtrain I have added an example to demonstrate what a prototype is. I'm not sure how much can be said about your fiddle. It looks like you are not creating multiple objects, but you just have one object with a method on it. There's nothing wrong with this, but in this case, you may be just as well off with an ordinary function.
2

Using the new keyword when you call a function sets the context (this) inside the function to be a newly instantiated object, rather than window or some other context, which is why you can assign to this.firstName inside the function, and then refer to it as person1.firstName.

Without using the new keyword, the value of this WONT be a blank object, so you will be assigning to window instead. In this case, you want to use new since you are using the function as a constructor. If you aren't planning to use the function as a constructor, you don't want to call it with new.

5 Comments

Is there any other apporach to make this kind of instances.. for knowledge i am asking...
Sure, you can just create them manually with object literals: var person1 = {firstName: "Alice"} or you can make a function that returns a new object that you create with a literal like this: var person = function(name){return {firstName: name}} and call it with person("Alice") but in this case, its more idiomatic to make a constructor function and call it with new like you are doing in the original question.
That looks pretty straightforward and has none of the complications of the original question.
yes, so instead of using new keyword, can't should i use this approach right? if so why... (sorry for bad questions)
For the example in your fiddle, what you have is fine. If this ob object is going to become something really complicated that is going to be carting along its own state, then you might want to think about making it more 'object oriented' by creating it with a constructor. Then you can have private variables (via closures) and inheritance (via prototypes) and that sort of thing. If your ob object is just going to be a store house for functions like init, then what you have is just fine.
2

Another possible structure using closures and not objects at all

This structure also can be nested creating private static variables

It has no use of the word this

var thing = function(private_var){

   function get(){
     console.log(private_var)
   }

   function set(z){
      private_var = z
   }

   return {
    get:get,
    set:set
   }


}

var x = thing(0)
var y = thing(1)

Please note :
This makes certain types of programmers freak out and panic

&& importantly x.say !== y.say

Comments

1

I think you need a bit better understanding of how objects and prototyping work in Javascript.

Consider you have a use case where you want an object that represents a user, and stores their first_name.

Without using any functions, you can simply create an object with your desired properties:

var person = {
    first_name: 'joel'
};

This is a standard javascript object - nothing special at all, and no usage of the new keyword to construct it. An alternate syntax to accomplish the same thing would be:

var person = new Object();
person.first_name = 'joel';

Again - this is just a standard object - nothing special at all.

The main reason for creating new instances of a function, is to use javascript's prototyping system. This is similar to a class in other languages. Let's say you wanted all instances of a person to have a method called getName(). You could either make sure you create that method on every person you have...

var person = {
    first_name: 'joel',
    getName: function() {
        return this.first_name;
    }
};

or...

var person = new Object();
person.first_name = 'joel';
person.getName = function() {
    return this.first_name;
};

However a better approach for this kind of thing, where you're always going to want this method defined for every user, is to create a new instance of a person object, and define the getName method on the prototype property of the Person function:

function Person() {}
Person.prototype.getName = function() {
    return this.first_name;
}

var user = new Person();
user.first_name = 'joel';
console.log(user.getName());

... Or as per your example, you can use a parameter to the Person constructor function to set the first name property:

function Person(first_name) {
    this.first_name = first_name;
}
Person.prototype.getName = function() {
    return this.first_name;
};
var user = new Person('joel');
console.log(user.getName());

Note that using this method you would always use the new keyword when creating a Person instance. The reason for this becomes clear when you consider the followng:

function Person() {this.first_name = 'joel'; return 'test';}
console.log(window.first_name); // Undefined, as expected
console.log(Person()); // Shows "test";
console.log(window.first_name); // shows "joel".
console.log(new Person()); // Shows "{first_name: 'joel'}"

Note that on line 4 above, you can see that by omitting the new keyword on a function call that expects you to be using it, you've accidentally modified a property on the window object, instead of setting it on a new regular object.

Effectively - you can consider usage of the new keyword to cause the return value of the Person function to be disrecarded, and instead you'll be given back a new instance of the Person Object.

Also note that you can reduce the risk of accidental modifying of the window object by omitting the new keyword from inside your function, by checking if this is equal to window and returning a new instance of your function instead:

function Person() {
    if (this === window) return new Person();
    this.first_name = 'joel';
}

With the above, you can instantiate your person object using either of the following methods and both will have the same effect:

var user1 = new Person();
var user2 = Person();

For some more information on how javascript functions and prototype objects work, I suggest reading http://www.w3schools.com/js/js_object_prototypes.asp

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.