Is it possible to create a JavaScript object without using a new keyword?

Here is what I would 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 easily an instance of a by connecting a to my prototype chain, but then I need to make new b() , which I am trying to avoid. I want this to be possible?

Update: I feel this is possible with a reasonable use of b.__proto__ = a.prototype . I will experiment more after work.

Update 2: The following is what seems like the closest you can get, which is enough for me. Thanks to everyone 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 on the blog on the Power Constructors blog as soon as I added the essential line b.__proto__ = a.prototype :

 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 
+15
javascript inheritance constructor prototype
Dec 11 '09 at 15:59
source share
13 answers

You can use this template:

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

after which you can:

 var myObj = SomeConstructor(); 

In addition to this (rather old) answer: you can use the module template 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 the jsFiddle for some Date function function that I created using this template.

+27
Dec 11 '09 at 17:50
source share

What is wrong with the new keyword?

Anyway, it seems that the best way is to read on Javascript inheritance: http://javascript.crockford.com/inheritance.html

+10
Dec 11 '09 at 16:04
source share

Someone posted an article by Douglas Crockford on this question, and he accurately explains what you are asking.

OO Javascript constructor constructor: neoclassical versus prototype

+4
Dec 11 '09 at 16:05
source share

You cannot avoid new in the general case (without going to extremes, according to Crockford Zoidberg's article indirectly related), if you want inheritance and instanceof work, but then (again), why do you need or need?

The only reason I can think about where you want to avoid this is to try passing the constructor function to another piece of code that does not know it as a constructor. In this case, just wrap it in the factory function:

 function b() { // ... } function makeB() { return new b(); } var c = makeB(); 
+3
Dec 11 '09 at 16:17
source share

A simple answer to your specific question: no.

This will help you determine why you want to avoid new . Perhaps the templates referenced by one of the other answers will help. However, none of them leads to instanceof returning true in your tests.

Essential new operation: -

 var x = (function(fn) { var r = {}; fn.call(r); return r;}(b); 

However, there is a difference in the fact that the fn construct is bound to the object using some internal property (yes, you can get it with constructor , but setting it does not have the same effect). The only way to get instanceof for the intended purpose is to use the new keyword.

+3
Dec 11 '09 at 16:21
source share

You can create instances without a new operator (here's a great article written about it by Douglas Crockford http://yuiblog.com/blog/2006/11/13/javascript-we-hardly-new-ya/ ). But that does not help you with the history of "instanceof".

+2
Dec 11 '09 at 16:04
source share

Yes you can do it.

 var User = function() { var privateMethod = function() { alert('hello'); } return { sayHello : function() { privateMethod(); this.done = true; } } } var user1 = User(); 

Is there something wrong with this method?

+2
Dec 18 '12 at 9:10
source share

The only way to get instanceof to work is to use a new keyword. instanceof exploits ____proto____, which is being installed new .

+1
Dec 11 '09 at 17:13
source share

JavaScript objects can be created without using a new keyword.

For example, the following function returns an object without using a new keyword

 function a () {
     var obj = {};
     obj.name = "hello";
     obj.age = 12;

     return obj;

 }
0
Dec 11 '09 at 16:54
source share

In the javascript shortcut, you can use eval (unescape ("...")) to create an object without the "new" operator:

 javascript:xhr=eval(unescape('new\x20XMLHttpRequest();'));alert(xhr); 
0
May 24 '13 at 13:43
source share

For those who can find this through Google (for example, I ...), I developed an original solution for wider use:

 var myObject = function() {}; // hint: Chrome debugger will name the created items 'myObject' var object = (function(myself, parent) { return function(myself, parent) { if(parent){ myself.prototype = parent; } myObject.prototype = myself.prototype; return new myObject(); }; })(); a = function(arg) { var me = object(a); me.param = arg; return me; }; b = function(arg) { var parent = a(arg), me = object(b, parent) ; return me; }; var instance1 = a(); var instance2 = b("hi there"); console.log("---------------------------") console.log('instance1 instance of a: ' + (instance1 instanceof a)) console.log('instance2 instance of b: ' + (instance2 instanceof b)) console.log('instance2 instance of a: ' + (instance2 instanceof a)) console.log('a() instance of a: ' + (a() instanceof a)) console.log(instance1.param) console.log(instance2.param) 
0
Jan 23 '15 at 17:38
source share

Using Object.create and classic Function.prototype . By creating a prototype chain correctly, you maintain the correct functioning of the instanceof keyword without using the new keyword.

 function A() { return Object.create(A.prototype); } function B() { return Object.create(B.prototype); } B.prototype = Object.create(A.prototype); var c = B(); assert(c instanceof A); assert(c instanceof B); 
0
Oct 17 '15 at 17:02
source share

Yes.

 function _new(classConstructor, ...args) { var obj = Object.create(classConstructor.prototype); classConstructor.call(obj, ...args); return obj; } function test_new() { function TestClass(name, location) { this._name = name; this._location = location; this.getName = function() { return this._name; } } TestClass.prototype.getLocation = function() { return this._location; } TestClass.prototype.setName = function(newName) { this._name = newName; } const a = new TestClass('anil', 'hyderabad'); const b = _new(TestClass, 'anil', 'hyderabad'); const assert = console.assert assert(a instanceof TestClass) assert(b instanceof TestClass) assert(a.constructor.name === 'TestClass'); assert(b.constructor.name === 'TestClass'); assert(a.getName() === b.getName()); assert(a.getLocation() === b.getLocation()); a.setName('kumar'); b.setName('kumar'); assert(a.getName() === b.getName()); console.log('All is well') } test_new() 

Link: https://gist.github.com/aniltallam/af358095bd6b36fa5d3dd773971f5fb7

0
Jan 17 '19 at 9:41
source share



All Articles