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
You can create instances without the new operator (here is a great article written about this by Douglas Crockford http://yuiblog.com/blog/2006/11/13/javascript-we-hardly-new-ya/). But it will not help you with the "instanceof" story.
By using Object.create and the classical Function.prototype. Setting up the prototype chain properly, you preserve proper functioning of the instanceof keyword without any use of 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);
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.
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()
Ref: https://gist.github.com/aniltallam/af358095bd6b36fa5d3dd773971f5fb7
In a javascript bookmarklet, you could use eval(unescape("...")) to create object without "new" operator:
javascript:xhr=eval(unescape('new\x20XMLHttpRequest();'));alert(xhr);
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