Preparing Yourself for Modern JavaScript Development
codethinked.com
codethinked.com
Thanks for the article though, if I ever need to write some JS this will help keep me a little more sane.
And even those Scheme uber-nerds considered it big hack, more useful in theory then in practice.
I don't deride PHP (I don't know it), but I see nothing wrong with IIFE. Yes, it could benefit from some syntactic sugar, but otherwise it is just using one of the best features of JavaScript, function support (first-class functions, anonymous functions, etc.).
It makes perfect sense to use a pattern like IIFE in order to encapsulate code, often using closures to allow access in a controlled manner from the outside, etc.
I suppose perhaps you don't like closures and so forth, and that's fine, but many people including me love them.
Language design by committee is seriously flawed and until a feature is shipping in all the major browsers it isn't real.
*depending on which version of ECMAscript is being used.
This means that the vm would be lowlevel enough that performance would start to approach that of native code, with complete freedom for the programmer to write the code for it in any language he desired.
The browser would then be able to execute this code instead of the corresponding Javascript file (e.g you compiler outputs two different object codes, one minified javascript for legacy browsers, one modern vm file for modern browsers).
That article starts from the assumption that any in browser VM will resemble the JVM; which is a faulty assumption. In fact, any in browser VM would have to be very different from the JVM since Rule 0 for any such VM would be "acceptable Javascript performance".
From that article:
> Meanwhile, JVMs don't do these optimizations. Since all types are statically
> known, the compiler knows exactly how much storage they need and what
> operations they support. It can then generate appropriate tight code for those
> types. This is fast if your language is statically typed, but if you're trying to
> compile a dynamically typed language to the JVM, it won't be able to run as fast as a
> VM that can assume dynamic typing all the way down and optimize specifically
> for that.
A whole wasted paragraph. Of course a browser VM wouldn't be statically typed, that'd make compiling/running Javascript a bear. One would hope there'd be some system of type-hinting, because eliminating dynamic dispatch is really low hanging fruit in terms of optimization, but JVM/CLR-style static typing? Madness.
Check out OneJS: http://github.com/azer/onejs
It's the only tool that lets you structure your client-side project as a CommonJS package and produces unobtrusive code mixable with anything in same global scope.
Friendly request for proof via examples. A gist would be fair.
you can see all the smelling shit of requirejs there.
> CommonJS defines a module format. Unfortunately, it was defined without giving browsers equal footing to other JavaScript environments. Because of that, there are CommonJS spec proposals for Transport formats and an asynchronous require.
"both RequireJS and Browserify are not even good options. Browserify's implementation is awkward, incomplete and pollutes global scope a lot. Check out OneJS"
I think there may be an agenda behind these comments.
"JavaScript: The Good Parts" by Douglas Crockford "JavaScript Patterns" by Stoyan Stefanov
Get cozy with them -- they're useful.
No. max line lengths is a style choice. indenting with spaces vs tabs is a style choice brace position is a style choice
Using prototypes and instances in JS is about using the right tool for the job.
It's not about modern web techniques, which is why it aged that well. For those, I'd personally recommend pulling apart some modern webapps or libraries, or reading modern tutorials. Usually you're somewhat outdated once your book reached its publisher… (Having said that, JavaScript Patterns is also pretty neat)
One cool fact is that Javascript has first class functions. This means you can bring a lot of development patterns from the functional realm into your web development.
There is a trend of languages moving away from the concept of mutable state. The article does a good job with the first steps (by wrapping everything in its own function scope), but Javascript lets us go further. The article seems like it attempts to shoe-horn the concepts of classes and sub-type polymorphism into a language that has better options.
It's amazing how few tutorials there are out there that fill in that gap between being a traditional web developer versed in .net / php and knowing the basics of javascript to being an actual javascript coder.
Most articles and tutorials around the web seem to target the beginner while most hacker news front page pieces target the advanced coder who already understands closures / prototypes etc and there seems to be very little in between.
(function(){//do some work})();
var Person = function (){ this.Save = function() { … }; };
var person = new Person(); person.Save();
The disadvantage however, is that the method is re-created once for each instance when the constructor runs, so they are not as memory-efficient as the prototype style.
Also, when you add methods to the prototype you affect all instances from the past and the future. So for example if you add a method to String.prototype, all current and future strings get it.
(function(){
})();A more memory-efficient approach:
var Person = (function(){
function Person(x){
this.x = x
}
function myPrivateMethod(x){
//...
}
Person.prototype.something = function(){
y = myPrivateMethod(this.x)
}
return Person
})()I think which to use depends on whether you believe private methods/variables are helpful or not. Some argue they are unnecessary and it's better to keep everything public. Some like to use a naming convention like an underscore prefix on private items, but declare them publicly.
You could also argue that private items are problematic if you start composing classes from other classes by extending. Then the new methods can't access the private state because they're in a different scope, whereas if they were on the prototype they could find it through `this`.
I've used both approaches but nowadays tend towards the prototype style as that seems to be the more accepted.
It could be just me but I cannot understand how that was/is/has been acceptable at all in the first place. Doesn't functions nested 11 levels deep (true story) ring any alarm bells for people?
(function(window, $, undefined){ //do some work }(window, jQuery));
If instead of immediately executing this function, we kept a reference to the function, then reference it, the function can be supplied with mocks for testing. Obviously there's an issue that you'd pollute the global namespace with this named function. So what's the best practice there?
oldJQuery = jQuery;
jQuery = mock;
//Run module
jQuery = oldJQuery;
Remember that IIFE's are basically equivalent to variable definition and assignment. The only reason we even have to go through the trouble of using them is due to JS not having block scope.A different approach that might work for me would be to subvert require.js, so that it pulls in mocks. I see there's other people thinking along the same lines: https://github.com/tigbro/requirejs-factory-plugin
i also highly recommend using popular frameworks and libraries, since lots of them use the tricks mentioned in your article.
Another thing that's worth noting is the JSON Object Notation: http://www.hunlock.com/blogs/Mastering_JSON_(_JavaScript_Obj...
very readable form of declaration.
Don't do it that way. If the Person constructor assigns any data, for example an array, that data will be shared with all instances of Spy. Most likely you don't want that. Instead call the Person constructor within the Spy constructor:
function Spy() {
Person.apply(this, arguments);
}
Spy.prototype = Person.prototype;
Spy.prototype.constructor = Spy; (new Person).constructor === SpyAttaching the "parent" prototype you want to have in the "child" prototype chain to a dummy constructor and new-ing that will do the trick for widest compatibility, although Object.create in ES5 and __proto__ (standardised) in ES6 both give you more direct access to the prototype chain:
function inherits(child, parent) {
var dummy = function() {}
dummy.prototype = parent.prototype
child.prototype = new dummy()
child.prototype.constructor = child
}
function Spy() {
Person.apply(this, arguments)
}
inherits(Spy, Person)