JavaScript - interesting trick, it is possible to create both class and function in one definition
In this article, we're going to have a look at how to create class that allows user to create object with or without new
operator in JavaScript.
Problem overview:
xxxxxxxxxx
function MyClass() { }
var object1 = MyClass();
var object2 = new MyClass(); // <----- how to make new operator optional?
Simple problem solutions are presented below:
In this case recept how to make new object for same class definition with and without new
keyword with strict mode is described.
Note: these approach work for web broser and NodeJS JavaScript with strict mode.
When this
is not defined new object is cteated and assigned to self
variable - it means ClassFunction
was called as function.
xxxxxxxxxx
'use strict'; // optional for NodeJS
var ClassFunction = function() {
var self = this || { };
self.printText = function(text) {
console.log(text);
};
return self;
};
var object1 = ClassFunction();
var object2 = new ClassFunction();
object1.printText('This text comes from function result object!');
object2.printText('This text comes from class instance object!');
Below example shows how to detect if new
keyword were used to create ClassFunction
.
xxxxxxxxxx
'use strict';
var ClassFunction = function() {
var self = this;
if (self instanceof ClassFunction) {
self.printText = function(text) {
console.log(text);
};
} else {
return new ClassFunction();
}
};
var object1 = ClassFunction();
var object2 = new ClassFunction();
object1.printText('This text comes from function result object!');
object2.printText('This text comes from class instance object!');
In this case recept how to make new object for same class definition with and without new
keyword without strict mode is described.
Note: this approach requires to adjust source code for web browser or node js - look on comment - to solve this problem check example 2.
xxxxxxxxxx
var ClassFunction = function() {
var self = (this == window || this == null ? {} : this); // for web browser
// var self = (this == global || this == null ? {} : this); // for nodejs
self.printText = function(text) {
console.log(text);
};
return self;
};
var object1 = ClassFunction();
var object2 = new ClassFunction();
object1.printText('This text comes from function result object!');
object2.printText('This text comes from class instance object!');
This universal approach is useful to write code for web browser and node js both.
xxxxxxxxxx
function getRoot() {
if (typeof window != 'undefined') {
return window;
}
if (typeof global != 'undefined') {
return global;
}
throw new Error('Unsupported platform!');
}
var root = getRoot();
root.createScope = function(self) {
return (self == root ? { } : self);
};
// Example:
var ClassFunction = function() {
var self = createScope(this);
self.printText = function(text) {
console.log(text);
};
return self;
}
var object1 = ClassFunction();
var object2 = new ClassFunction();
object1.printText('This text comes from function result object!');
object2.printText('This text comes from class instance object!');