r/javascript • u/arcxyz • Mar 09 '15
Things every JavaScript developer should know
http://ilikekillnerds.com/2015/03/things-every-javascript-developer-should-know/74
u/ambalbemuth Mar 09 '15
I also agree js devs shlould learn js.
3
2
u/ambalbemuth Mar 10 '15
To add something of actual value, I would recommend this talk from jsconf about the event loop. I've been doing JS for a few years but that talk made me feel like a noob for not knowing which parts belong to the runtime and which are external APIs. To catch your interest "if you grep the V8 source code for setTimeout, it's not in there".
3
Mar 09 '15
Cool. This talks about some useful dev tools functionality also. Specifically console functions beyond log and error. Such as "copy".
7
Mar 09 '15
Yeah, but really?
If I'm to hire a dev I expect them to know how to use relevant dev tools. X devs should have knowledge about X's dev tools.
9
u/lordxeon Mar 09 '15
Knowing how to use a tool, and knowing of a new feature that was only added very recently are not the same.
You can use the Chrome Dev Tools all you want and never known about the "copy" feature yet still be an excellent JS developer.
I would not base my hiring decisions on weather or not the person knew some obscure feature of their program.
2
u/x-skeww Mar 09 '15
2
2
u/Sinistralis Mar 11 '15
That command line API is brand new to me, holy crap.
I am just now breaking into writting proper testable code and one of the things on my TODO list is to externalize logging levels for JS (passed from the server) so we could flick on proper debugging tools in a dev environment, and all of this...
I've never been so excited about debugging before.
1
12
u/thinkvitamin Mar 09 '15
"Because Node.js is Javascript at its core, the learning curve is non-existent if you already no a little bit of Javascript."
9
Mar 09 '15
And bs, the learning curve is non-existent.
Yes, it's still Javascript but it's an entirely different library. That's like saying someone who knows jQuery knows Angular since they're both built on JS.
5
u/SingularityNow Mar 09 '15
It could probably be argued that knowing a language has little to do with how well you know its associated libraries and frameworks.
2
1
Mar 17 '15
Also, a completely different context; back-end anything has a different set of concerns from the client side. While the language might be the same more or less as it were, the audience is completely different.
Know your audience.
2
19
u/retroriffer Mar 09 '15
Great post. It should also mention closures and how to write asynchronously ( given its single-threaded nature )
9
u/calsosta Mar 09 '15
Also pass by reference/value, dot-notation/bracket-notation, closures and how to defend yourself against programming bullies.
20
u/dukerutledge Mar 09 '15
TLDR: All JS dev's should read one of the great introductory books on JavaScript.
0
Mar 09 '15
[deleted]
6
u/tententai Mar 09 '15
I liked "Javascript, the good parts" by D. Crockford (a good starting point, though not the easiest read), "Eloquent Javascript" by M. Harverbeke (it has nice practical examples) and "Learning JavaScript Design Patterns" by A. Osmani (more advanced since it's specifically about patterns, read this one after the other 2).
3
u/dukerutledge Mar 09 '15
JavaScript The Good Parts
Is a good quick read. It isn't perfect and it eschews many more complicated topics for ease of use, but it hits a lot of good stuff.
You Don't Know JS
This series of books gives a deeper dive into many specific areas of JavaScript. Kyle does a nice job of breaking things down, but it is a series, not one book.
1
u/thejameskyle Mar 10 '15
I would not recommend YDKJS, but whatever.
Also check out Eloquent JavaScript. It's written by Marijn Haverbeke (CodeMirror, Tern, Acorn, etc.) and it's a great book on programming in general. Available freely with Creative Commons licensing.
3
Mar 09 '15
Eloquent JavaScript. I'm reading it now, it's really well written, gives a lot of practical examples, and goes beyond JavaScript and into the programming and browser side. It's free to read online at eloquentjavascript.net, the website also contains environments to practice.
6
Mar 09 '15
Am I missing something? The .call and .apply examples both show .call method.
8
16
u/cosinezero Mar 09 '15
"for (condition 1; condition 2; condition 3)"
...um.
4
u/cosinezero Mar 09 '15
So everyone downvoting me prefers to have three conditions in their FOR loops, eh? How's that working out for ya?
2
2
1
2
Mar 09 '15 edited Mar 09 '15
I don't know why you got downvoted. Condition1 and condition3 are not even conditions. Condition1 is 'do this piece of code on begin', and condition3 is 'do this piece of code every iteration given condition2 is true'. Only condition2 is a condition.
5
3
u/straatman Mar 09 '15
Iirc the correct terms are, intitializer, condition, incrementor (depending on operation)
5
u/Freakazette Mar 09 '15
I only started learning like... a month ago, I guess - Codecademy knows but I'm too lazy to look - but this blog makes me feel not so bad. Like, I lurk and I feel stupid, but I know how to FizzBuzz, I knew the difference between == and ===, I know many of the loops, and most everything under working with strings - I might not completely suck at learning. And what I don't know - well, these things take time.
Thank you for my confidence boost.
4
u/rooktakesqueen Mar 09 '15
As a rule of thumb: ALWAYS define your variables at the top of your desired scope. If you are using ‘use strict’; at the top of your script files (or within your functions), an error will be thrown if you try using a variable before it has been defined.
Most Javascript linters like Jshint will complain if you haven’t defined ‘use strict’ anyway, so provided you’re applying best practices it should be impossible to use variables before they are defined.
Everything after the first sentence describes why the first sentence is wrong...
1
Mar 10 '15 edited Mar 10 '15
Yah. Stupid. But it got published. Down votes because I have an opinion.
4
u/Blitzsturm Mar 09 '15
To mash a few things together in an unclean but working fashion, this is an amusing trick:
[].forEach.call(document.querySelectorAll("button[class=flat-button]"), function(o, i)
{
o.style.border = "1px solid red";
});2
u/ejfrodo Mar 09 '15
good article for noobs, but in the example code for "An example using .apply:", it still uses the .call() instead of .apply()
3
Mar 09 '15
No mention of prototypal inheritance? I think that's a bit more important than most things on this list.
5
u/MrBester Mar 09 '15
Oh, shush you. People don't need to know that as everything is frameworks and classical OO twisted to fit in the confines of the language (and therefore why "JavaScript sucks" is considered a valid opinion). Who needs to care how the language actually works?
1
1
u/Sinistralis Mar 11 '15
I'm personally not a fan of the prototypal approach. I like the classless object approach where you return an object that is essentially an interface into the guts of the real object (abstracts everything away except what the implementor needs, and it forces you to write modular code). I find it to be much cleaner and easier to work with, and I'm honestly surprised it isn't mentioned more.
1
Mar 11 '15
I used to like that method as well. And it is useful in some contexts, but it's akin to private methods/properties in classes due to the closure. This makes it inherently impossible to test the inner guts in an automated fashion. But TDD experts will tell you that private methods aren't supposed to be tested anyway :)
To each their own.
1
u/Sinistralis Mar 11 '15
It's similar yes but it comes with a lot of advantages IMO. From a testing perspective, it forces you to write modules. There is no reason that module could not return an interface that hooks into a unit test so it can get at the guts, and make that only exposable in a development environment.
5
1
1
u/back-stabbath Mar 10 '15
I'm not quite understanding
while (i--){ ..... }
So when i equals zero, the loop breaks because 0 is sort of equal to false? Is this a safe solution?
1
u/ambalbemuth Mar 10 '15
As long as i isn't modified anywhere else and starts being an integer > 0, why wouldn't it?
1
u/kyrul Mar 10 '15
I think the only way it'd be unsafe is if multiple things were modifying i, such that it could decrement to a negative number in the span of the loop
1
1
u/_basem_ Mar 10 '15
Issues like == and variable hoisting are actually taken for granted, as most of us will always avoid it even though we might forgot the reason for it
1
-1
Mar 09 '15
I disagree about call and apply though. I prefer to never use:
new
this (one exception)
Object.create
bind
call
apply
When I avoid this list my code tends to be smaller and faster to execute. You don't need OOP in this language, thanks to lexical scope, to achieve decomposable reuse and reference sharing.
The one exception for this is event handlers where it is commonly necessary to access the event target without access to an explicit reference.
12
u/Vheissu_ Mar 09 '15
It might not be a requirement to use call or apply, but I think as a developer it is important to know about them and how they work though. Until ES6 is better supported, we're stuck with call, apply and bind. Javascript is a complex beast, I think it is important to know about many facets even if you don't use them. Spread operators are the future.
1
Mar 09 '15
Until ES6 is better supported, we're stuck with call, apply and bind.
I don't see why ES6 is a factor in that discussion. I have seen several posts comments in this sub-reddit that make it sound like developers need ES6 right now just to write code, as though they cannot possibly write JavaScript without something like Babel.js.
I am curious where this line of thinking comes from. Maybe those people are all incredibly new to JavaScript or maybe they have never learned to build large applications in this language without it looking like Java. I would like to learn more about why people are forming such conclusions.
2
u/moreteam Mar 09 '15
In the case of
call/apply: They are the only way to "simulate" argument forwarding in ES5. For example the following ES6 code:function traceAndCall(fn, ...args) { console.log("Called function"); fn(...args); }To write something similar in ES5 you need apply. Or in other words:
Until ES6 is better supported, we're stuck with call, apply and bind.
0
Mar 09 '15
Apply and call allow execution of a function by reference with something explicit passed in as a value for this. If you don't use this then you don't need call or apply. Call, apply, and bind are all new with ES5. I absolutely promise you can program large elegant decomposable applications without these.
2
u/moreteam Mar 09 '15
No,
applyalso allows passing varargs into a function. That it also supports passing in an explicitthiscontext isn't important here. My example makes no reference to anythis, so I'm confused why you would bring that up. Also,applyandcallare not ES5. I'm not sure where that idea comes from.bind- yes. But the other two are ES3. But just out of curiosity - maybe I'm missing something. How would you implement the following ES3 snippet withoutapplyorcall?function traceAndCall(fn) { console.log("Called function"); fn.apply([].slice.call(arguments, 1)); }I'm not saying that this is the kind of code you'd have all over the place. I'm just saying that you will be using it one way or another. Hiding it behind a lodash helper doesn't count.
P.S.: That snippet is the pre-ES6 version of the above ES6 code.
0
Mar 09 '15 edited Mar 10 '15
It is generally considered bad form to pass arguments of unknown type or quantity into a function. This makes the reference invocation (function arguments are reference declarations) challenging to predict, which interferes with compilation in the JIT. I am sure this may be of great convenience to your code, but I would recommend against it.
6
u/moreteam Mar 09 '15
That's a great non-answer to the question, completely ignoring that your previous post:
Contained wrong information about the availability of
applyandcallDisregarded use of
applyfor non-method functionsAlso forwarding
argumentscan have no impact on JIT-ability of your code. And let's not even talk about the whole "optimize if there's a problem, write reasonable code otherwise". You needapplyfor implementing a generic partial application function. If you say "generic partial application should not exist!" then you are working against the language - which is bad style.1
Mar 09 '15
You need apply for implementing a generic partial application function.
I am not trying to argue with you. This is not my holy war. I don't need
applyand I choose to never use it when building large complex applications. Therefore it is completely unnecessary.arguments of variable type and quantity do have an impact on JIT performance. This is expressed from numerous browser vendors. If you think I am wrong then do a jsperf test. I know this is sloppy coding, so I will never use it. But this is just my personal opinion. I am not telling you what to do and I am certainly not trying to argue with you.
If you say "generic partial application should not exist!" then you are working against the language - which is bad style.
I don't know what that is and it is certainly something I would never use.
2
u/moreteam Mar 09 '15
partial(myFn, "a", 3)- that's a generic partial application.myFncan have a fixed set of arguments. It doesn't have to be polymorphic. Butpartialis polymorphic. Which is fine, it's supposed to be. You can start writingpartial1,partial2,partial3, ... functions - but as I said: that's working against the language. It's like using Java and writingMyThingListclasses instead of using generic lists.2
u/MrBester Mar 09 '15
It is generally considered bad form to pass arguments of unknown type or quantity into a function.
FTFY
0
Mar 09 '15
[deleted]
1
u/wiseaus_stunt_double .preventDefault() Mar 10 '15
bind is new in ES5, but call and apply aren't. At least, I hope call and apply existed before ES5, or I won't know how to write that polyfill for bind.
-1
1
u/zoeshadow Mar 09 '15
Fat arrow functions lexically bind this value, so it is more predictable for people coming from other languages.
When you have window as a this value it doesn't help anyone, it's clearly not intended, and depending in the caller of the function to call it correctly is risky
0
Mar 09 '15 edited Mar 09 '15
I completely agree, which is more reason to avoid to my above mentioned list.
I can understand why that would make ES6 more desirable, but not why so many developers on here sound as if they cannot live without it. How can people not live without it if these features are less than a year old in the browser and ES6 is not even finished yet?
2
u/zoeshadow Mar 09 '15
It's hard to explain, but for me is all about familiarity, my first language was Java, and I also use Java on the server. So when I write
thisI expect it to be something. Using ES6 short function syntax I can write safer code. I could write Javascript without using this but is not a real alternative when you use most of the real world frameworks.And the short syntax helps to improve readability and reusability of functions!
3
u/MrBester Mar 09 '15
See, that's a problem. It's all very nice having these short forms, but readability for those used to a different language is not a valid reason for having them. Does Spanish add arbitrary constructs to make it easier for English speakers?
4
u/oefig Mar 09 '15
Could you explain further in what ways bind/call/apply can affect performance? I love using
bindto set up my handler functions like so:$element.addEventListener('click', someHandler.bind(this, 'foo'))... over:
$element.addEventListener('click', function() { someHandler('foo'); });I always thought
.bindand.applyfit well into Javascript, but if I shouldn't be using them please tell me why!2
u/cosinezero Mar 09 '15
Could you explain further in what ways bind/call/apply can affect performance?
Not quite sure I can explain the whys, but I can certainly show you the benchmarks with various ways of calling things: http://jsperf.com/javascript-bind-vs-function
Of interest to you is the poor performance of the very first test.
3
Mar 09 '15
Thanks for this. All the more reason to avoid bind.
4
u/nschubach Mar 09 '15
Is it really? You have a click event on a button. If you are able to click that button a thousand times a second, I might see a reason to care about a few clock ticks of performance, but for the use case bind provides an easy readable way to implement event binding.
0
u/cosinezero Mar 09 '15
Oh, I can name you a few times it's worth using bind. Currying, for instance. But you should avoid bind unless you need it. Simply using it to permanently set scope is not a good usage; use an anonymous call (apparently not apply!!) for that.
It is strange that apply is slow; I would think that would be optimized better than call.
1
u/Sinistralis Mar 11 '15
Why would you use bind for currying?
function sub_curry(fn /*, variable number of args */) { var args = [].slice.call(arguments, 1); return function () { return fn.apply(this, args.concat(toArray(arguments))); }; }0
Mar 09 '15
It completely agree it is definitely worth using bind to ensure that this is commonly understood and doesn't get lost. If you don't use this, though, you don't need bind.
1
u/cosinezero Mar 09 '15
Er, currying. Doesn't necessarily require use of this, but used to bind a parameter value to a function.
See http://kishorelive.com/2012/02/06/currying-in-javascript-using-bind/
2
Mar 09 '15 edited Mar 09 '15
EDIT Bind is very slow: http://jsperf.com/javascript-bind-vs-function
Bind and apply are not likely to significantly impact performance enough to measure.It is not for performance reasons that I avoid these. I don't use them is because they are unnecessary.Coming from a C++ like language you absolutely need this stuff. You need classes and a way to extend those classes or reference an object property in relation to a known context. Each of these features requires code definitions (overhead). A code author has to manually write code to define points of inheritance and bindings that connect various objects together and establish the organization of the code.
C++ has been around since 1982 and did not get lexical scope until 2008 (i think). Java did not get lexical scope until April 2014 (hasn't even been a year). A functional approach to writing code is available to these languages now, but it has not always been that way. Developer who grew up in those language only know the OO way that requires lots of code overhead. The OO way is not absolutely necessary any more in these languages, but this line of thinking is institutionalized.
JavaScript had lexical scope in 1995 when it was born. The advantage to lexical scope is that you don't have to define any of the organizing facets. The inheritance model is simply understood by the language directly from nesting of scopes. The way it works is if a reference is defined in an outer scope it is available (immediately) to an inner scope. You just directly call the outer reference as though it were local to the nested scope. The advantage is that you can still establish a public/private model of organization, reuse and sharing, and inheritance (of scope) without doing anything more than nesting the scopes.
I wrote about closures and lexical scope in feature explanation and abstractly.
The lexical scope chain is the primary means of reference resolution in JavaScript and the prototype chain is a secondary means of reference resolution. When a reference is encountered (at execution time) it must be resolved, which means finding where it was declared and what its value is. The lexical scope chain is searched first and if the reference cannot be found the prototype chain is searched. The total difference in performance is likely negligible because the JIT engine will attempt to cache the declaration point as much as possible. The primary performance difference is noticed from having less code to execute (and fewer references) to achieve the same result.
My thoughts are if I can get away with writing (and maintaining) substantially less code then any performance benefits are merely serendipity. Fortunately, writing less code happens to mean faster execution almost universally.
2
u/Sinistralis Mar 11 '15 edited Mar 11 '15
This was exactly my thought process the whole time. There is an approach to object creation where you return an interface of the object, and it forces you to write amazing code, and it completely does away with new, this, Object, and bind. Call and Apply are solved by just being smart about how you pass objects around to functions.
On top of this, it lets you build objects in a way that each object only has EXACTLY what it needs to get it's job done, and absolutely no more. It's a completely different type of inheritance, and it works with JS so well.
Thank you for making me feel less insane.
3
u/nieuweyork Mar 09 '15
Would you care to expand on that? I've found that my code speeds up massively using object oriented style.
2
Mar 09 '15 edited Mar 09 '15
OOP code tends to require substantial boiler plate. Any speed improvement you notice likely comes from two things:
various mappings to references in memory (memory conservation and caching)
JIT optimizations
The memory reuse architecture for OOP in this language are prototypes. ES6 classes even desugar to prototypes. Prototype resolution is secondary to normal reference resolution in the lexical scope chain.
I prefer to code to the scope chain only (architecture of nested scopes). From what I have seen this approach is the fastest to execute in this language, but it has some minor draw backs with garbage collection. Since (prior to ES6) JavaScript does not have anything like a standard IO or module system a purely lexical approach tends to produce large functions or an object containing various large functions. Larger objects take longer for garbage collection to remove.
Using the memory allocation tool for Chrome from Paul Irish I can see that my purely lexical application is garbage collected just fine, but it takes longer to collect between code runs. If code runs too frequently against a large enough input memory consumption continues to rise until execution frequency slows. OOP code is likely have this problem because it is less likely to squeeze everything into a common scope, or collections that come together to share a common scope.
I tend to not worry about memory, though, in this language because its not something you have any control over. Typically its something that don't have any visibility on. Execution time, though, is very simple to profile, observe, and reduce.
2
Mar 09 '15
I don't think you can go much further without call, bind, this and new.
Also if you have ever used jQuery then your not-to-use list makes no sense in your application.
4
Mar 09 '15
I have never been a huge fan of jQuery, but I am absolutely confident that I don't need any of the above list to work seamlessly with jQuery.
2
Mar 09 '15
I also try not to depend on jQuery when things can be done using native JavaScript. What I was trying to say is jQuery uses the above APIs so much that they will be used anyways if someone decides to use jQuery.
0
Mar 09 '15
[deleted]
1
Mar 09 '15
I attempted a guide at my approach, which somewhat explains it by example. I need to do some work to make architectural application of this approach more clear. I plan on updating that guide over the next couple of days.
0
Mar 09 '15
[deleted]
3
u/cwbrandsma Mar 09 '15
I'd argue you are being overly pedantic as few people really mean never when they say never (and same for always)...tends to be "never user this unless you can't get around it".
Under that context, I agree with him/her: I don't use 'new' unless there is no other way, and anytime I see a 'new' being required I chalk that up as another JavaScriptism that was f'ed up and should have been done another way.
2
u/MrBester Mar 09 '15
What is fucked up is having to write defensive code to cater for the dickheads who decide that a keyword in the language isn't worth bothering with when instantiating a NEW instance of something.
0
Mar 09 '15
[deleted]
0
Mar 09 '15
because it's obvious bullshit.
The message served no purpose except obvious trolling.
I think cwbrandsma is trying to point out that you are trolling, but I guess you didn't get the hint. I was not trying to pick a fight. If I said something to make you emotionally unstable just consider it a difference of opinion and move on.
3
Mar 09 '15
[removed] — view removed comment
-4
Mar 09 '15
You are being silly. You don't need to specify arguments or an explicit return value to achieve functional programming. Functional programming is not about using functions to pass things around (as a substitute for objects). It is about organizing instructions into containers that can be executed without regard for a returned value.
2
Mar 09 '15
[removed] — view removed comment
-3
Mar 09 '15
I don't know what a partial function is, but it sounds like something I would never do.
7
Mar 09 '15
[removed] — view removed comment
0
Mar 09 '15 edited Mar 09 '15
I don't use call or apply because they are unnecessary. I don't use the
argumentsarray in functions.argumentsis generally considered very bad form, because it allows use of arguments with flexibility to types and quantity of arguments passed into the function. This is makes it hard for the JIT compilers to compile those functions, which means the code will execute far more slowly.
-18
u/spiphy Mar 09 '15
There are a few developers out there, like me, that have no use for the DOM or browser developer tools. I work on a C++ program with V8 embedded. My JavaScript code never runs in a browser.
20
28
u/cgaudreau senior HTML9 engineer Mar 09 '15 edited Mar 09 '15
Good article. However, correct me if I'm wrong, but the provided FizzBuzz implementation appears to be incorrect. On multiples of 15, the provided solution would print "FizzBuzz Fizz Buzz".
EDIT: the author fixed it after I posted. The original example had no elses or else ifs.