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