Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I construct a JavaScript object without using the new keyword?

Tags:

Here is what I'd like to do:

function a() {   // ... } function b() {   //  Some magic, return a new object. } var c = b();  c instanceof b // -> true c instanceof a // -> true b instanceof a // -> true 

Is it possible? I can make b be an instance of a easily by hooking a into its prototype chain but then I have to do new b(), which is what I'm trying to avoid. Is what I want possible?

Update: I feel that it might be possible with judicious use of b.__proto__ = a.prototype. I'm going to experiment more after work.

Update 2: Below is what seems to be the closest you can get, which is good enough for me. Thanks all for the interesting answers.

function a() {   // ... } function b() {   if (!(this instanceof arguments.callee)) {     return new arguments.callee();   } } b.__proto__ = a.prototype  var c = b(); c instanceof b // -> true c instanceof a // -> false b instanceof a // -> true 

Update 3: I found exactly what I wanted in a blog post on 'power constructors', once I added the essential b.__proto__ = a.prototype line:

var object = (function() {      function F() {}      return function(o) {          F.prototype = o;          return new F();      }; })();  function a(proto) {   var p = object(proto || a.prototype);   return p; }  function b(proto) {   var g = object(a(proto || b.prototype));   return g; } b.prototype = object(a.prototype); b.__proto__ = a.prototype;  var c = b(); c instanceof b // -> true c instanceof a // -> true b instanceof a // -> true a() instanceof a // -> true 
like image 928
pr1001 Avatar asked Dec 11 '09 15:12

pr1001


People also ask

Is new keyword required in JavaScript?

The new keyword is used in javascript to create a object from a constructor function. The new keyword has to be placed before the constructor function call and will do the following things: Creates a new object. Sets the prototype of this object to the constructor function's prototype property.

Can constructor be called without new?

No, this is not possible. Constructors that are created using the class keyword can only be constructed with new , if they are [[call]]ed without they always throw a TypeError 1 (and there's not even a way to detect this from the outside).

What happens if you don't use new JavaScript?

It is NOT 'bad' to use the new keyword. But if you forget it, you will be calling the object constructor as a regular function. If your constructor doesn't check its execution context then it won't notice that 'this' points to different object (ordinarily the global object) instead of the new instance.

Which JS keyword is used to create an object?

Creating a JavaScript Object Create a single object, with the keyword new . Define an object constructor, and then create objects of the constructed type.


2 Answers

You can use this pattern:

function SomeConstructor(){    if (!(this instanceof SomeConstructor)){         return new SomeConstructor();    }    //the constructor properties and methods here } 

after which you can do:

var myObj = SomeConstructor(); 

In addition to this (rather old) answer: you can use a module pattern to create an object:

function Person(name, age, male) {   name = name || 'unknown';   age = age || 0;   function get() {     return ['This person is called ', name,             (!male ? ', her' : ', his'),' age is ',             age].join('');   }   function setAge(nwage) {      age = nwage;   }   return Object.freeze({get: get, setAge: setAge}); } // usage var jane =  Person('Jane', 23)    ,charles = Person('Charles', 32, 1)    ,mary = Person('Mary', 16);  console.log(jane.get()); //=> This person is called Jane, her age is 23 mary.setAge(17); console.log(mary.get()); //=> This person is called Mary, her age is 17 

Here's a jsFiddle for some Date functionallity I created using that pattern.

like image 128
KooiInc Avatar answered Oct 07 '22 02:10

KooiInc


What's wrong with using the new keyword?

At any rate, it sounds like the best thing to do is read up on Javascript inheritance: http://javascript.crockford.com/inheritance.html

like image 35
Matt Ball Avatar answered Oct 07 '22 00:10

Matt Ball