I have been reading JavaScript Patterns book by Stoyan Stefanov and one of the patterns to enforcing the new operator for constructor functions goes like this
function Waffle() {
if (!(this instanceof Waffle)) {
return new Waffle();
}
this.tastes = "yummy";
}
Waffle.prototype.wantAnother = true;
when writing this way you can invoke Waffle either one of these ways
var first = new Waffle(),
second = Waffle();
I think this is a helpful feature not sure if it's implemented in future versions of ecma/javascript
I came up with something on my own that I thought could just copy and paste each time when creating a constructor function
something like this
function checkInstance (name) {
if (name.constructor.name === undefined) {
return "construct it"
} else {
return false;
}
}
function Waffle() {
var _self = checkInstance.call(this, this);
if (_self === "construct it") {
return new Waffle()
}
this.tastes = "yummy"
}
var waffle = Waffle()
waffle
Therefore I can invoke Waffle either way new Waffle or Waffle() and still have it return an object
My problem that I'm having is here
if (_self === "construct it") {
return new Waffle()
}
Is there anyway I can refer to new Waffle()
without referring to the actual name of the constructor function meaning so I could copy and paste this each time and not have to change anything. Meaning I could I save Waffle() as a variable and do something like
return new var
I wish I could use this.name but that doesn't work either until it is invoked.
I have a feeling I can't but wanted to at least ask some of the people here on stack overflow if it was a possibility
Again your comments and feedback is appreciated
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.
You may not know it, but you've used a JavaScript design pattern. Design patterns are reusable solutions to commonly occurring problems in software design. During any language's lifespan, many such reusable solutions are made and tested by a large number of developers from that language's community.
The book explores the capabilities and pitfalls of object-oriented programming, and describes 23 useful patterns that you can implement to solve common programming problems. These patterns are not algorithms or specific implementations.
When a function is called with the new keyword, the function will be used as a constructor. new will do the following things: Creates a blank, plain JavaScript object. For convenience, let's call it newInstance .
I have a better solution. This is what you're currently doing:
function Waffle() {
if (!(this instanceof Waffle))
return new Waffle;
this.tastes = "yummy";
}
Waffle.prototype.wantAnother = true;
This pattern isn't really nice because you're mixing the code to construct a new object with the code to check if the new
keyword is being used.
I've mentioned before that you shouldn't use the new
keyword in JavaScript as it breaks functional features. Instead let's create another function which does the same thing:
Function.prototype.new = (function () {
return function () {
functor.prototype = this.prototype;
return new functor(this, arguments);
};
function functor(constructor, args) {
return constructor.apply(this, args);
}
}());
This function allows you to create an instance of a function as follows:
var waffle = Waffle.new();
However we don't want to use new
at all. So to do away with it we'll create a function which wraps a constructor as follows:
function constructible(constructor) {
function functor() { return Function.new.apply(constructor, arguments); }
functor.prototype = constructor.prototype;
return functor;
}
Now we can define the Waffle
function as follows:
var Waffle = constructible(function () {
this.tastes = "yummy";
});
Waffle.prototype.wantAnother = true;
Now you can create objects with or without using new
:
var first = new Waffle;
var second = Waffle();
Note: The constructible
function is pretty slow. Use the following version of constructible
instead - it's a little faster:
function constructible(constructor) {
constructor = Function.bind.bind(constructor, null);
function functor() { return new (constructor.apply(null, arguments)); }
functor.prototype = constructor.prototype;
return functor;
}
Personally I wouldn't use either of these two methods. I would just remember to write new
, or (more likely) I would restructure my code as follows:
var waffle = {
create: function () {
var waffle = Object.create(this);
waffle.tastes = "yummy";
return waffle;
},
wantAnother: true
};
var first = waffle.create();
var second = waffle.create();
If you want to know more about this pattern then read the following answer: https://stackoverflow.com/a/17008403/783743
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With