Firstly arguments.callee
is deprecated in ES5 strict so we don't use it. The real solution is rather simple.
You don't use new
at all.
var Make = function () {
if (Object.getPrototypeOf(this) !== Make.prototype) {
var o = Object.create(Make.prototype);
o.constructor.apply(o, arguments);
return o;
}
...
}
That's a right pain in the ass right?
Try enhance
var Make = enhance(function () {
...
});
var enhance = function (constr) {
return function () {
if (Object.getPrototypeOf(this) !== constr.prototype) {
var o = Object.create(constr.prototype);
constr.apply(o, arguments);
return o;
}
return constr.apply(this, arguments);
}
}
Now of course this requires ES5, but everyone uses the ES5-shim right?
You may also be interested in alternative js OO patterns
As an aside you can replace option two with
var Make = function () {
var that = Object.create(Make.prototype);
// use that
return that;
}
In case you want your own ES5 Object.create
shim then it's really easy
Object.create = function (proto) {
var dummy = function () {};
dummy.prototype = proto;
return new dummy;
};
There is nothing wrong in using $
in variables. I wouldn't do it on purpose on every variable, but it's still a valid syntax. jQuery is one of the examples where $
is used as a variable name. That's also why "Chrome dev tools don't always see this is a Javascript error", because there is no error in the first place.
If you are afraid of writing code like:
var demo = function demo() {
var a = 123;
...
$a = 456; // A new variable is created in global scope.
}
then you have to use a style checker, like jsLint, jsHint or Google Closure Linter. Which one of those? It's up to you to make a choice. To help you with that, here are a few notes:
Style
Google Closure Linter follows Google JavaScript Style Guide, known to be cleverly done. Using a well-known style for JavaScript or any of six other languages is a good idea: when you share your code or hire a new developer, chances are they are already familiar with this style.
Many developers are familiar with Douglas Crockford style as well. This style is explained in detail in JavaScript: The Good Parts, a book worth be bought by anyone who works with JavaScript.
As for jsHint, I can't really find what conventions are used, and the website itself seems to avoid talking about that subject. Maybe I missed something.
Support by IDEs
Both jsLint and jsHint are supported by PhpStorm. This is also the case of Google Closure Linter.
Environment
Google Closure Linter is one of a series of tools. If you're already using Google Closure Compiler or Google Closure Library, it would be preferable to chose Closure Linter above other tools.
Strictness
jsLint is known to be strict. jsHint is more permissive, which is not always a good thing. For example, one of the reasons to fork jsLint for jsHint is explained in an article which shows bad code which will produce a error in jsLint, but not in jsHint:
/*global jQuery */
// Example taken from jQuery 1.4.2 source
jQuery.extend({
/* ... */
isEmptyObject: function( obj ) {
for ( var name in obj ) {
return false;
}
return true;
}
/* ... */
});
The code is bad, because it looks like JavaScript has block scope, while it hasn't. See JavaScript: The Good Parts, p. 102, Appendix A: Awful Parts, Scope. In other words, looking at the code without knowing the language, we expect name
to not being visible outside the loop, while it will remain visible.
As for Google Closure Linter, I believe that it's somewhere in the middle between jsLint and jsHint, but I haven't enough information to support that.
Conclusion
I would avoid jsHint: it's too permissive, meaning that it would not find potential bugs the other linters would detect. The style guide which is used is difficult to find.
Among jsLint and Google Closure Linter, the choice isn't obvious. Both are written by experts, both follow strict, well described style guide already followed by thousands of developers. Use both for some time, then pick one which is more practical for you.
Best Answer
Because this code would evaluate to 'Default Value' everytime you passed in 0, "", false, or some other falsy value.
It might not bite you on how you use this particular function, but it is a bad pattern to avoid when you do care about passing in things like empty strings or 0 or a boolean.