JavaScript: The Good Parts - How to not use `new` at all
Solution 1
Crockford gives an example for an object creation function as should have been provided by JS itself in one of his Javascript talks available on http://developer.yahoo.com/yui/theater/
However, the YUI(3) team itself uses "new", and they DO follow his recommendations (since he's the Yahoo chief JS architect (UPDATE: he moved on, but the statement was true when this response was originally written). I understand this particular statement to be more on an "academic" level, what SHOULD have been HAD the language been designed "right" and not with some leftovers of the class-based inheritance stuff. He (IMHO rightly) says that the way it turned out JS is conflicted, prototype based but with this one thing from "classical class" inheritance languages.
However, JS is as it is so go and use "new".
You can find his object creation function here: http://javascript.crockford.com/prototypal.html
if (typeof Object.create !== 'function') {
Object.create = function (o) {
function F() {}
F.prototype = o;
return new F();
};
}
newObject = Object.create(oldObject);
EDIT: Updated to use Crockford's latest version of that function - there are three.
UPDATE June 2015: We have had Object.create(...)
for quite a while now, which all current browsers support (incl. IE 9 and above), so there was no need to use Crockford's function.
However, it turns out that if you use Object.create
you should make sure that you don't do that a lot: That function is FAR slower than using new Constructor()
!
See http://mrale.ph/blog/2014/07/30/constructor-vs-objectcreate.html for an explanation (for the V8 engine), and see http://jsperf.com/object-create-vs-crockford-vs-jorge-vs-constructor/62 for a performance demo.
Another reason to not turn your back on new Constructor(...)
is that ES6 classes will surely see wide-ranging adoption even if only for the simple reason that most Javascript developers come from class-based languages.
Also check out this article, which argues for Object.create
: http://davidwalsh.name/javascript-objects-deconstruction
Like it or not, especially in projects you want to share with a wide range of people (in space and time -- meaning right nor or over time, other people taking over from you) there are more reasons for using new
.
UPDATE September 2015: For myself, I have begun to use ES 2015 Javascript for everything - using either io.js and/or Babel. I also don't use any new
in my projects except for the Javascript built-ins like new Error(...)
. I prefer to use the far more powerful functional approach, I completely ignore the object system. [my-object].prototype
and this
are completely gone from my projects. For the longest time I was VERY skeptical of these ideas "because objects work just fine". But after very reluctantly giving it a try at the beginning of a new (io.js) project it "clicked" and I don't understand why I wasted two decades. Okay, not quite, today the JS engines and hardware are much more conducive to that style. Especially with ES 2015, I recommend giving a functional style entirely free of any this
and class
(the new ES 2015 keyword or the entire concept, based on using constructorFn.prototype
) a try. It may take you a few weeks but once it "clicks" I promise you won't ever go back - not voluntarily. It's so much more convenient and more powerful.
UPDATE February 2018: While I still do what I wrote in the previous update I now want to add that sometimes classes are fine. There are no absolutes. :-)
Solution 2
I don't know how to avoid new Date()
or new XMLHttpRequest()
either. But I do know how to avoid using new for my own types.
First, I start with Object.create()
. This is an ES5 method, so it's not available everywhere. I add it using the es5-shim, ad then I'm ready to go.
I like the module pattern, so I start by wrapping my type in a self-executing anonymous function, var Xyz = (function() {...})()
. This means I have a private space to work without making a mess in the global namespace. I return an object with a create()
function, and a prototype
property. the create()
function is for users of my type. When they want one, they call Xyz.create()
, and get back a new, initialized object of my type. The prototype
property is available if people want to inherit.
Here's an example:
var Vehicle = (function(){
var exports = {};
exports.prototype = {};
exports.prototype.init = function() {
this.mph = 5;
};
exports.prototype.go = function() {
console.log("Going " + this.mph.toString() + " mph.");
};
exports.create = function() {
var ret = Object.create(exports.prototype);
ret.init();
return ret;
};
return exports;
})();
and inheritance looks like this:
var Car = (function () {
var exports = {};
exports.prototype = Object.create(Vehicle.prototype);
exports.prototype.init = function() {
Vehicle.prototype.init.apply(this, arguments);
this.wheels = 4;
};
exports.create = function() {
var ret = Object.create(exports.prototype);
ret.init();
return ret;
};
return exports;
})();
Solution 3
Not using new
and blindly following Crockford is silly.
Understand JavaScript and write good code. Using the new
keyword is the Cornerstone of JavaScript OO.
You are going to miss out on a lot of good JavaScript code by avoiding new
.
Rather than arbitrarily cutting huge chunks out of your toolkit, learn it and use it properly instead.
Crockford has a habit of saying that anything in JavaScript which ever gave him a bug in his code is bad.
I would personally go on to say that "[a]n even better coping strategy is to be competent."
Solution 4
You can avoid new
by creating factory functions:
var today = Date.getToday();
(In case you were wondering, you can't avoid it on the factory function itself:)
Date.getToday = function() { return new Date(); };
Although I only think you should create such functions if it adds semantic value (as in the case above) or if you can default some of the constructor parameters. In other words, don't do it just to avoid using new
.
Solution 5
This question has already been asked and answered: Is JavaScript's "new" keyword considered harmful?
As Raynos said, blindly following Crockford (or anyone else for that matter) without understanding why they say the things they do, is silly.
![Admin](/assets/logo_square_200-5d0d61d6853298bd2a4fe063103715b4daf2819fc21225efa21dfb93e61952ea.png)
Admin
Updated on July 08, 2022Comments
-
Admin almost 2 years
Crockford's book, JavaScript: The Good Parts, says (on page 114) that constructor functions should always be given names with an initial capital letter (ie. Point), and that function names with initial capital letters should only be used with constructor functions (everything else should be lowerCase).
This convention helps us avoid forgetting to use the
new
operator with constructor functions.He goes on to say that "[a]n even better coping strategy is to not use
new
at all."My question is, how do we program JavaScript without using
new
at all?- We can avoid
new Object()
andnew Array()
with the literal{}
and[]
. - We can avoid
new Number()
,new Boolean()
, andnew String()
with0
,true
and''
. - We can avoid
new RegExp()
with something like/pattern/
.
How do we avoid
new Date()
?And, most importantly, how do we avoid using
new
with our own custom Objects? - We can avoid