9 ms·
Preparing Yourself for Modern JavaScript Development
- SonicSoul 14y agogreat post, thanks. 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_Object_Notation_) http://www.hunlock.com/blogs/Mastering_JSON_(_JavaScript_Obj... very readable form of declaration.
- Hovertruck 14y ago"JSON Object Notation" => JavaScript Object Notation Object Notation
- lucianop 14y agohttps://en.wikipedia.org/wiki/RAS_syndrome https://en.wikipedia.org/wiki/RAS_syndrome
- ender7 14y agoThis is a nice, gentle introduction, but if you're going to start using modules you might as well go slightly farther and use something like RequireJS (http://requirejs.org/ http://requirejs.org/) or Browserify (https://github.com/substack/node-browserify https://github.com/substack/node-browserify).
- mozillarewind 14y agoAnd then migrate to native ES6 modules when they're implemented: http://wiki.ecmascript.org/doku.php?id=harmony:modules http://wiki.ecmascript.org/doku.php?id=harmony:modules
- diamondhead 14y agoBoth RequireJS and Browserify are not even good options. Browserify's implementation is awkward, incomplete and pollutes global scope a lot. Check out OneJS: http://github.com/azer/onejs http://github.com/azer/onejs it's the only tool that lets you structure your clientside project as a commonjs package and produces unobtrusive code mixable with other code in same global scope
- combataircraft 14y agoboth RequireJS and Browserify are not good options. Browserify's implementation is awkward, incomplete and pollutes global scopa a lot. Check out OneJS: http://github.com/azer/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.
- iron_ball 14y agoWhat's specifically wrong with RequireJS? I haven't heard much discussion of it, and you only addressed Browserify in your comment.
- combataircraft 14y agoI've been following the work on RequireJS for two years and think that it's an evil project that sabotages the rise of CommonJS, NodeJS and NPM by leading client-side Javascript coders to follow a non-standard, awkward way of JS development. From the very beginning, it forces coders to cover their code with awkward code and maintain it manually. It's completely insane. I even think that I'm wasting my time by talking about it.
- wilmoore 14y ago> it forces coders to cover their code with awkward code and maintain it manually Friendly request for proof via examples. A gist would be fair.
- combataircraft 14y agohere; http://requirejs.org/docs/ http://requirejs.org/docs/ you can see all the smelling shit of requirejs there.
- cfjedimaster 14y agoThat's not really an answer. What _about_ their way of doing things do you consider to be wrong and why?
- wickedchicken 14y agoI always find it odd that the same developers who deride PHP look at things like IIFE and think "wow, JS is a cool, modern language!" Thanks for the article though, if I ever need to write some JS this will help keep me a little more sane.
- ufo 14y agoThe first time I saw something like IIFEs was in one of the SICP lectures, where they show that variable definitions with let or define can be seen as syntactic sugar over immediately invoked lambdas. And even those Scheme uber-nerds considered it big hack, more useful in theory then in practice.
- silentbicycle 14y agoIt's useful as a de-sugaring step during compilation, not something people generally do by hand.
- ufo 14y agoContinuation Passing Style is also supposed to be used as part of acompilation step but look at how everyone does in by hand in Javascript-land :(
- silentbicycle 14y agoFor real. I tried to find a way to point that out without sounding snarky, gave up.
- azakai 14y ago> I always find it odd that the same developers who deride PHP look at things like IIFE and think "wow, JS is a cool, modern language!" 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.
- bazzargh 14y agoI'd be interested if one of these articles on modularity also addressed testability. For example, the IIFE pattern in the article: (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?
- ufo 14y agoI don't think you need to go through all the trouble. Some thing like the following should be enough: 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.
- bazzargh 14y agoYeah, I'm aware I can do that, but it gets a bit painful for code that is stateful & executes on load (like IIFE does). You end up having to write a separate test script to run in a separate process for each test case...way slower than if you can isolate the module and 'restart' it in a closure for each test. 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 https://github.com/tigbro/requirejs-factory-plugin
- pgambling 14y agoHere are a couple book recommendations for those of you looking to improve your JavaScript: "JavaScript: The Good Parts" by Douglas Crockford "JavaScript Patterns" by Stoyan Stefanov
- thealphanerd 14y agoI've been working on following the good parts for my latest project. I've started to cringe any time people talk about the prototype or using "this"
- jashkenas 14y agoThat's unfortunate. Properly using prototypes and "this" is the only way to do high-performance JavaScript with objects. Get cozy with them -- they're useful.
- TazeTSchnitzel 14y agoIt isn't the only way, it's just that browser JS engines tend to be optimised for them.
- andybak 14y agoI believe your statement is therefore equivalent to the preceding one.
- stephenr 14y agoI cringe when people claim to be writing more than the most basic JS and aren't using prototypes.
- ahoge 14y agoIt's a style choice. You don't have to use classes and/or do anything with the prototype chain.
- deleted 14y ago[deleted]
- beambot 14y agoI'm not a Javascript developer... but that IIFE syntax strongly reminds me of LISP. (function(){//do some work})();
- MBlume 14y agoMy "breakthrough moment" with Javascript was realizing that I could just treat it like scheme.
- TimJRobinson 14y agoThis is the kind of article I really needed to read 18 months ago instead of fumbling my way through it by myself. 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.
- Xcelerate 14y agoThat was a well-written article that has a pattern that should work well for a lot of people. But I think it can be improved. 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.
- alttab 14y agoOne time I saw a some code where the author re-implemented haskell in javascript. Needless to say reading that code was nearly impossible!
- aymeric 14y agoWhat is the difference between using the prototype technique shown in the article and this? var Person = function (){ this.Save = function() { … }; }; var person = new Person(); person.Save();
- jamiemill 14y agoThat's called a "privileged method". The advantage of those is that they can access any private variables from the constructor, and they keep those variables in scope for their lifetime. 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.
- aymeric 14y agoShould I be concerned about the additional memory my way of doing things takes? It seems more convenient, allows for private methods and a limited drawback in my view (memory is rarely a bottleneck)
- ricardobeat 14y agowhy private methods?
- aymeric 14y agovar Person = function() { var privateMethod = function() {...}; };
- ricardobeat 14y agowhy: what's your reasoning for using them? 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 })()
- MatthewPhillips 14y ago> Spy.prototype = new Person(); 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;
- jashkenas 14y agoDude, that's a pretty awful way to do it. After running your example code: (new Person).constructor === Spy
- insin 14y agoPerson will also have anything you add to Spy's prototype if you do that. Attaching 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)