Tuesday, October 18, 2016

Tips and misunderstood features that every programmer should know about HTML/CSS/JavaScript

This post is a compilation of tricks for web development. I'll continue to update the list as I come across new points. The focus will be on small facts about HTML, CSS, JavaScript that are largely misunderstood or waste time (especially the first time you encounter them), but I won't touch on helpful third party frameworks much.  To submit a fact (or correction) for this list, post it in the comments section or email me.

Bookmark this page and check back often for new tips all the time. Don't forget to follow me on Twitter.

HTML

  • For <!doctype html>, the doctype is case-insensitive. This is valid in all compliant HTML parsers, but is not correct in XML.
  • When using the <script> tag, specifying type="text/javascript" is optional. JavaScript is already the default programming language in all browsers.
  • In HTML5, the <head> tag is obsolete. Put your metas, scripts, titles, and so on directly in the <html> tag, but outside <body>.

JavaScript

  • If you're not sure whether you should use == or ===, just remember that " " == 0 is true, but " " === 0 is false. 
  • Also, true == 1, but true != 2.
  • To use a switch statement with conditions, do this:
    switch(true){
        case boolean_condition1:
            //Code
            break;
        case boolean_condition2:
            //Code
            break;
    }
  • The double tilde trick in JavaScript is frequently used to floor numbers (~~3.9 == 3). But never use it.
  • In JQuery, if you use the empty or remove functions, JavaScript's garbage collector will delete any references to event handlers for the deleted components. If you remove stuff that has JavaScript events attached using something like document.getElementById("foobar").innerHTML = "", you could leak memory.
  • If you want to transfer data from your server to JavaScript via your rendering engine, one possible hack is by writing data to a var, for instance:
    var value = {{myNumber}};
    var value = <?= echo myNumber ?>; 
    var value = @(ViewBag.myNumber);
    Or whatever... But if you're worried that the value might not exist on the server, use this instead: var value = Number("{{myNumber}}"); so that if the value doesn't exist, it won't crash the client side with an "expected value after =" error.
  • The return keyword breaks if the return value is on a separate line. Semicolons are optional and JavaScript can be lazy in unexpected ways.
  • You don't need jQuery to use css selectors to query elements in JavaScript. document.querySelectorAll() is an underrated built-in function that does nearly the same thing (though jQuery does add some nice features).

CSS

  • When positioning elements as absolute, the target will, by default, be positioned relative to the window, unless one of the target's parents (or ancestors) are positioned as anything except static. So if a container is positioned as relative, it's children can be positioned as absolute, and setting things like left: 0, etc. on the child will position it relative to the parent.

Like I said, it's a work in progress. More to come.

Monday, September 19, 2016

Make node auto-restart on Windows

Whether it's recovering from an unexpected crash, or doing a quick reboot to update the server code, this four-line batch file is what you're looking for.

:start
node app.js
echo %date% %time% >> rebootlog.txt
goto :start

The third line is important here. Don't neglect proper logging or you might not realize there was any crash at all. After all, the point of this is to reduce downtime, not lazy error handling.

Happy coding.

Sunday, August 28, 2016

The double-tilde (~~x) technique in JavaScript - What it is, and why you should be careful about using it.

Watch



What is it?

The ~ (tilde) operator in JavaScript is the often-overlooked bit-wise not. For integers, it is the equivalent to running:

~x == -(x + 1)

So ~(10) will give you -11. There's another caveat to the ~ operator. It casts floating point numbers to integers by dropping everything after the decimal. So in the more general sense,

~x == -(Math.trunc(x) + 1)

Recall that Math.trunc() is kind of like Math.floor(), except the value (positive or negative) will always be rounded towards 0. The ~~ technique is a common trick you'll find a lot of developers using. Let's resolve it:

~~x = -(Math.trunc(-(Math.trunc(x) + 1)) + 1)
-(Math.trunc(-(Math.trunc(x)) - 1) + 1)
-(Math.trunc(-(Math.trunc(x))) + 1 - 1)
-(Math.trunc(-(Math.trunc(x))))
= --Math.trunc(x)
Math.trunc(x)

Essentially, ~~ is used as a short-hand hack for Math.trunc(). 

But you should probably never use it.

I'm pretty lazy so I use to use this a lot... until it got me in trouble. It turns out that ~~ doesn't work for really large numbers. For instance, when I run ~~1000000000000, the result is -727279968, so in this case not only did we lose a ton of precision, the answer actually has the wrong sign! So if you were expecting a positive number because the input was positive, this type of thing can really wreak havoc, like crashing your Node.js server or whatever.

But even if you understand the way that numbers work in JavaScript and only use the ~~ trick where appropriate, I would still contend that using this technique is detrimental in the same way as goto statements or the xor swap algorithm. It's esoteric, and prone to bugs. It is not beginner-friendly, doesn't come with documentation, and if accepted by convention could lead unknowing developers down the path to buggy code.

Alternative?

Instead of using ~~ just stick with Math.floor(). If you want a way to truncate decimals (flooring both positive and negative numbers towards 0), add this declaration at the top of your code:

if(!Math.trunc){
    Math.trunc = function(value){
        return Math.sign(value) * Math.floor(Math.abs(value));
    }
}

Note that Math.trunc() is already available in ECMAScript 6 compliant JavaScript engines (which is used by most modern browsers, but not all), and doesn't need to be added in those environments.


Tuesday, August 9, 2016

Add sleeps or yields to JavaScript loops with Sequencr.js

Add sleeps or yields to JavaScript loops with Sequencr.js

Ever wish JavaScript had a built-in sleep function to help you build loops for computationally difficult tasks without killing the browser? Yea, we all have. Obviously we can always cascade setTimeouts, but can get messy fairly quickly.

Recently, I published a JavaScript library, Sequencr.js, that's helped me with this problem. It's fairly simple, but so deceptively useful that I've found myself using it in tons of different projects. Check out the project page:


Enjoy!

Update

Sequencr.js is now  a fully functional promise library. It makes promises a lot easier to work with and adds some interesting design patterns like asynchronous promise-based iterators.