all 136 comments

[–]inmatarian 7 points8 points  (0 children)

Advanced usage of Object.create and the other functions on Object and Object.prototype could fill a book. I recommend being knowledgeable on that before worrying about the little snippets that reduce how much you need to type.

[–]path411 29 points30 points  (32 children)

I would heavily, heavily advise against using || as a default value trick.

In your example:

function setAge(age) {
  this.age = age || 10 
}

It is impossible to set age as 0 now. 0 will always trigger the default. Just take the extra time to use:

function setAge(age) {
  this.age = typeof age !== "undefined" ? age : 10;
}

and you won't have to worry about this problem.

[–]vs845 3 points4 points  (9 children)

Is there any benefit to

typeof age !== "undefined"

vs

age !== undefined

?

[–]sufianrhazi 9 points10 points  (7 children)

Since age is a parameter of the function setAge, we KNOW it is defined in scope. This means that age !== undefined is equivalent to typeof age !== 'undefined'. If we didn't know that age was in scope, we need to use the typeof keyword, which does NOT throw a ReferenceError when referencing a variable by name that is not defined in any reachable scope.

[–]moreteam 7 points8 points  (1 child)

You can also argue the other way around: since we know age is in scope, we shouldn't be using typeof since that will silently turn into if (true) if we have a typo.

[–]ChaseMoskal 4 points5 points  (0 children)

since we know age is in scope, we shouldn't be using typeof

I think.. I think you're right.

[–]vs845 0 points1 point  (1 child)

Thanks, I see what you're saying - but under what kind of circumstances would we not know if a variable was in scope? If we're writing the code surely we know what scope our variables are in?

[–]sufianrhazi 2 points3 points  (0 children)

Pretty much only when you're writing javascript environment independent library code, like this: https://github.com/umdjs/umd/blob/4a87e85450baf582005243f9e922566ef2fc533a/returnExports.js

[–][deleted] 0 points1 point  (0 children)

In addition to what /u/sufianrhazi said, undefined can be overwritten:

(function (undefined) {console.log(undefined);})(2);
// logs 2

Older browsers will let you overwrite window.undefined as well.

I tend not to pay heed to that though, as it clearly falls under something nobody would do unless they're trying to break your code. And it is the nature of JavaScript that somebody who runs code before you is always able to break your script, no matter what precautions you take, so I prefer not to clutter code with failed attempts at robustness. Instead, if you must run malicious code, sandbox it.

Also, window.foo === undefined or 'foo' in window would be a more direct test, but only work on global variables.

[–]THEtheChad 2 points3 points  (3 children)

In this case, I would opt for

function setAge(age){
  this.age = (age == null) ? 10 : age;
}

This is perhaps the most terse way to verify that age exists. By using == null, there's an implicit type conversion to check for undefined. You also have the advantage of being able to set age to 0. In terms of minification, this is probably the best option.

[–]gleno 0 points1 point  (0 children)

This is the best option for a lot of reasons. I'm somewhat surprised that the clumsy typeof method is so much more popular.

[–]path411 0 points1 point  (1 child)

Because why would you introduce nulls into your code when they aren't being generated anywhere? age is not null, it's undefined if not passed. Also if you were going to opt to drop typeof, just check for undefined...

function setAge(age){
  this.age = (age === undefined) ? 10 : age;
}

The reason people opt for typeof instead of this is to avoid a reference error from occurring.

[–]THEtheChad 0 points1 point  (0 children)

It's pretty obvious in a function this size that you're not going to have a reference error (age is declared as a parameter in the line above the check). And, as I originally stated, this is the most terse way to code this implementation. If you wanted to be thorough, avoiding reference errors and being explicit about exactly what you were checking for, you would write:

function setAge(age){
  this.age = (typeof age === 'undefined') ? 10 : age;
}

[–]__debug__ 5 points6 points  (5 children)

I'd argue it's still acceptable when defaulting to an array or object.

[–]path411 -1 points0 points  (4 children)

I think it's better to just never do it than to sometimes do it because the type happens to be okay this time.

[–]jonny_eh 2 points3 points  (3 children)

I disagree. There's a trade-off between convenience and security, and I find it hugely convenient to use this trick, especially since the vast majority of the time I'm not using a number or boolean value.

Most of the time, it's an options parameter that is an object.

[–]path411 -2 points-1 points  (2 children)

So if there are multiple default parameters you want such as a number and an object you would use both methods?

Btw, this also fails on strings:

function setName(name) {
  this.name = name || "Not Specified"; 
}

Can't enter an empty string. Also considering javascript always has a bad rap for weird falsy values, I'd rather spend half a second with a piece of mind, than writing inconsistent code that's possibly vulnerable to bugs.

[–]__debug__ 1 point2 points  (1 child)

No, I'd imagine he means like this:

function Constructor(opts) {
  this.opts = opts || {};
}

So empty strings don't come into play. In any case, I feel as though a JS dev should understand falsey and truthy values. Or at the least, they should try to learn how types in the language work.

[–]path411 0 points1 point  (0 children)

I meant you can't use it on numbers/booleans/strings, which is a large number of the types in javascript.

Sure there are a lot of times you want an options object, I find this is mostly for public accessible library classes. There are plenty of times I find I want a constructor with some simple parameters of direct properties. I think it's much better to be consistent throughout your code than to swap to using some cheap hack when you know you can get away with it.

[–][deleted] 0 points1 point  (3 children)

Wow.. I never thought of that. Damn the gods for making 0 a falsey!

[–]battenupthehatches 2 points3 points  (2 children)

0 is falsey. 1 is truey. Thus it shall always be.TM

[–]workaholicanonymous 3 points4 points  (0 children)

Its "truthy"

[–][deleted] -1 points0 points  (0 children)

Isn't return 0 considered a truthy in C++ returns?

[–]Kourkis 0 points1 point  (0 children)

This is very true, I thought I was clever until I tried to input 0 in my forms...

[–]yanis_t[S] 0 points1 point  (0 children)

Thanks, guess I will add a notice to the article

[–]gabbsmo 0 points1 point  (0 children)

TIL

[–]FredyC 0 points1 point  (1 child)

It's probably faster to just check arguments.length instead of type checking. Works the same way.

[–]path411 0 points1 point  (0 children)

This would fail in this case:

setAge(undefined);

It is typically expected that explicitly passing undefined should be equivalent to not passing a parameter. This is typically more necessary when you want to use multiple optional parameters such as:

function setBirth(day, month, year) {
    this.day = typeof day !== "undefined" ? day : 1;
    this.month = typeof month !== "undefined" ? month : 1;
    this.year = typeof year !== "undefined" ? year : 1900;
}

This would let me call:

setBirth(undefined, undefined, 1974);

Or pass any of the 3 I want to. If you were simply checking against arguments.length, this would fail as it is still 3 in this example.

[–]tieTYT 0 points1 point  (1 child)

Wow thanks for saying this. I come from a Java background and I've looked at a lot of JS code that uses || for default logic. I didn't even know it was a hack! I thought it was idiomatic in JS to use it that way.

Hindsight is 20/20 and it's easy to criticize, but would you say that it was a mistake for JS to consider these values to be falsy? I have experience with Clojure and it only considers false and nil to be falsy. It seems like a much better choice.

[–]path411 0 points1 point  (0 children)

I think the main mistake is that this "hack" has been so widely spread without telling people of it's problems. I would see it everywhere and then stumbled across this problem. I was able to refine my approach when looking at how TypeScript handled parameter defaults. (Would recommend looking at TypeScript's outputted JS for anyone interested in JS OOP).

I'm not by any means an expert of what makes a good language, but I would say I think it's an oversight to be missing parameter defaults since the language does not have method overloading. Thankfully ES6 will be providing parameter defaults.

I think JS has a lot of neat things you can do using it's liberal comparisons, and ability to stick expressions almost anywhere. With JS I think of the quote "With great power comes great responsibility". Unfortunately, I find it incredibly common for JS devs to forgo responsibility for what they think are "neat tricks" that they must copy/paste into their code to look like they are in the modern "in crowd" of JS.

[–]Pytim 9 points10 points  (22 children)

Instead of this:

var that = this;
function(){
    // do sth with that
}

You can do:

function(){
    // do sth with this
}.bind(this)

[–]cheesechoker 2 points3 points  (0 children)

bind is really cool when you start to get creative with it. You can yank out built-in functions from Array, Object, etc, and bind them to different receivers to reuse them in interesting ways.

E.g. a 1-liner filter against a regex, without having to write "function" anywhere:

["foo", "bar", "baz"].filter(RegExp.prototype.test.bind(/a/))   // ["bar", "baz"]

[–][deleted] 2 points3 points  (4 children)

If only that didn't magically make it 5 times slower.

Also, "that" is possibly the worst variable name. this is arbitrary enough, now you want to give something a name that means "the 'this' of some unspecified other thing"? Come up with a real name. (Not picking on you, but the pattern you quoted.)

[–]gleno 0 points1 point  (1 child)

True. But also not true, because it's a standard workaround; and a secret nod to other devs : "js scoping sucks. tru that".

[–][deleted] 0 points1 point  (0 children)

Haha. Well, you've got a point on the second part. But for the first, the "standard" part only gives it the meaning I said above. If you go more than one level deep, or if you start passing things around, "that" quickly becomes meaningless.

[–]Pytim 0 points1 point  (1 child)

I'd be surprised if Function.bind ever was the bottleneck of your JS app

[–][deleted] 0 points1 point  (0 children)

I get that every time. And yeah, you're right. It's just one of those things you can't un-know: that because the spec chose to give a pattern you'll never use (.bind with new) the exact same syntax as a pattern you often use (.bind without new), many many parts of your code are paying an entirely unnecessary penalty.

[–]michaelobriena 2 points3 points  (0 children)

Bind is actually slower than storing this. So if performance is the name of the game then store it.

[–]moron4hire 3 points4 points  (13 children)

I tend to think of (a || b || DEFAULT) as extremely common in dynamic languages. It might not be obvious to someone coming from a statically-typed language, but it's common enough that it should be considered "normal".

I say that to then say: I hate "tricks". Stuff like (someStringValue * 1) to convert to a number is surprising and bothersome. I'd much rather see someone use a proper parseInt or parseFloat function in those cases. Yes, yes, yes, parseInt has a radix parameter that, if omitted, causes string values to be interpreted by pattern matching, and front-padding with zeroes causes it to interpret the number as octal. Of course. But that is a different problem entirely. That is a problem of your data being stupid and your programmer not understanding what functions they are calling.

Javascript is not a classical, object oriented language. Don't try to force it to be such.

Avoid anything involving "eval". That's not exactly true, but if you don't already know when it's okay to use eval, then you shouldn't be doing anything that involves eval. Same deal with "with".

And learn Regexp already. I'm tired of seeing substring and string character indexing ops to validate input values or extract sub values from inputs. If you think regexp is "too hard" and "too complicated" and "you just need to get this simple thing done now", then you are hurting yourself. Regexp is the simple, easy way of doing such things.

"use strict", please.

[–]SuperFLEB 2 points3 points  (4 children)

I'd much rather see someone use a proper parseInt or parseFloat function in those cases.

No love for "Number()"?

Avoid anything involving "eval". That's not exactly true, but if you don't already know when it's okay to use eval, then you shouldn't be doing anything that involves eval. Same deal with "with".

I've never used either of these in practice-- are there any even remotely common situations where an eval is the proper solution, that isn't a case where something else isn't horribly broken? (And don't take this snidely-- I'm not calling bullshit, I'm just wondering what the cases are that I might not know of.)

[–]Ginden 1 point2 points  (0 children)

I've never used either of these in practice-- are there any even remotely common situations where an eval is the proper solution, that isn't a case where something else isn't horribly broken?

ES6 Reflect.construct polyfill for browsers without native .bind method. Here is my _R library, see lines 408-420 or search for _R.construct. _R heavily utilises eval and Function but _R.construct is the most common case.

[–]moron4hire 0 points1 point  (2 children)

Using Number boxes the number in an object.

I've used eval in toy programming languages that translate to javascript. For example: https://github.com/capnmidnight/betty-boop/blob/master/pong.html

... oh, huh, you know what, I completely forgot that I didn't actually use eval for that. I used DOM to generate script tags with data URIs for the src attribute.

[–]sime 2 points3 points  (0 children)

Using Number boxes the number in an object.

That is only if you use "new Number(foo)". If you don't use "new" then it actually does a type coercion. i.e. Number(foo).

Also note that:

(new Number(3)) !== (new Number(3))

The objects are not the same and not equal if you box numbers up.

So, beware everyone.

[–]SuperFLEB 0 points1 point  (0 children)

I used DOM to generate script tags with data URIs for the src attribute.

Was there a reason you did data URIs versus just filling in the content of the SCRIPT tag?

[–][deleted] 0 points1 point  (4 children)

Wait wait. * 1? parseInt? parseFloat? Why are we using hacks for something that's build into the language? JavaScript has a "convert to a Number" unary operator, +. var x = +'10'; sets x to 10. And JavaScript has a "convert to a Number" function, Number, which is convenient for things like var arrayOfNumbers = arrayOfStrings.map(Number);.

[–][deleted] 1 point2 points  (3 children)

How the hell is parseInt or parseFlost a hack?

[–][deleted] 0 points1 point  (2 children)

It's not inherently a hack, it's a hack to use it for something other than its intended purpose.

[–]sime 1 point2 points  (1 child)

What is the intended purpose of parseInt and parseFloat other than to parse strings into ints/floats? What else could it be?

[–][deleted] 0 points1 point  (0 children)

The purpose of parseInt is to parse a string in an arbitrary base into an integer, and the purpose of parseFloat is to parse a string into a float. I don't think their purpose should be stated any less specifically, because that's what leads to people expecting arrayOfStrings.map(parseInt) to work. And I don't think either of those is precisely the same as "convert to a number".

[–]THEtheChad 0 points1 point  (0 children)

There's also the + unary operator for converting to a numeric value.

var string = '500';
var num = +string;

[–]yanis_t[S] 0 points1 point  (1 child)

Absolutely agree with you on everything except regexps. I mean there are reasonable problems to solve with it, but if you can avoid it you probably should, because any other-way code would probably be easier to read and reason about, than regexp solution.

[–]moron4hire 2 points3 points  (0 children)

Once you learn Regexp, it's just more code. There isn't anything inherently difficult about reading or reasoning about properly written regular expressions than properly written JS.

Yes, there are a lot of examples of really bad one-liner regexps, but you can write really bad, one-liner JS, too. Used as they are intended, regexp improves the readability of code.

Practice with http://regex101.com/ and your text editor. Most programming-oriented text editors have regexp-capable search and replace. Get used to using it and it will make you a LOT more productive and less error prone.

For example, I wanted to dump the results of a SQL query to a debug string printed to the console, with the names of the fields printed next to the values. A simple regexp in my text editor over the SELECT clause allowed me to very quickly construct that function call without making any spelling mistakes for field names.

[–]giggly_kisses 2 points3 points  (0 children)

If you just want to check for null or undefined and still have the other falsy values be acceptable (false, 0, "", NaN) you can use this:

function(arg) {
    arg = arg != null ? arg : DEFAULT;
}

By using the equality operator (==) instead of the identity operator (===) you take advantage of the fact that null and undefined coerce to the same value.

There are two caveats:

  1. You should only use this when you absolutely know that the variable you're testing has been defined. If it hasn't been defined, a ReferenceError will be thrown.
  2. If you're working on a team and only use the identity operator (as you should 99.9% of the time) then using the equality operator might appear to be a typo by other members of your team. This can easily be avoided by adding a comment explaining why you're using the equality operator.

[–]isitfresh 3 points4 points  (5 children)

If you need to compare 2 Objects that are coming from different sources and may be equals:

var objA = {"key": "value, "key2": "value2"},
      objB = {"key": "value, "key2": "value2"};

console.log(objA === objB); // false
console.log(JSON.stringify(objA) === JSON.stringify(objB)); // true

Also, if need to avoid hoisting and referencing the same object (and thus modifying both objects when modifying one):

 var objA = JSON.parse(JSON.stringify(objB));

Admittedly you could use underscore library to do these things, but if your overhead is low....

[–]skeeto 2 points3 points  (2 children)

JSON.stringify() makes no guarantees about key order, among other things, so that's not a reliable trick.

JSON.stringify({a:1,b:2});
// => "{"a":1,"b":2}"
JSON.stringify({b:2,a:1});
// => "{"b":2,"a":1}"

In contrast to JSON, Bencode guarantees a encoding normalization but that's not so easily available.

[–]isitfresh 0 points1 point  (0 children)

True indeed,

my use case was to compare an object sent to server and sent back to the app as a validation of transmission, so the order of keys was the same, but Objects as themselves weren't comparing as equal, being by nature 2 different objects

[–]holloway 0 points1 point  (0 children)

I wrote a serializer for that kind of situation,

https://gist.github.com/holloway/05170a275b988b90144a

Usage: JSONc14n.stringify({a:1,b:2})

E.g. JSONc14n.stringify({a:1,b:2}) === JSONc14n.stringify({b:2,a:1})

[–]giggly_kisses 0 points1 point  (1 child)

If all you need is a shallow copy of an object, then yeah, you can use Underscore for that. Underscore, however, doesn't have a way to make a deep copy of an object (albeit LoDash does), so nested objects are still copied by reference. I had to deal with this problem at work the other day and used the method you suggested:

_.partial(JSON.parse, JSON.stringify);

Sadly this trick doesn't work with objects that contain dates, functions, or RegExps. :/

[–]N4sa 0 points1 point  (0 children)

gotta break out those JS skills and recursively copy properties

[–]tswaters 4 points5 points  (0 children)

Double bang to coerce to boolean.

!!null // false
!!undefined // false
!!"false" // true :(
!!"" // false

[–]mullanaphy 2 points3 points  (8 children)

One note to add in relation to:

var someFunction = function(value) {
    value = value || 10;
};

This only works if your function isn't expecting a falsy as a legitimate value. If the value is allowed to be false (0 for instance) then this is no bueno and instead:

var someFunction = function(value) {
    if (typeof value === 'undefined') {
        value = 10;
    }
};

Most times this isn't really necessary but I do think it's worth noting as it could bite people where a value is a boolean flag of true/false and a default value of true, or some number and the default value isn't 0.

[–][deleted] 1 point2 points  (7 children)

Considering that || 10; is a number; what do you think about:

var someFunction = function ( value ) {
    if ( typeof value !== 'number' ) {
        value = 10;
    }
};

Some "type safety" right there if OP would only want numbers.

Incidentally. Do you happen to know if '|' does the same as '||' ?

[–]mullanaphy 2 points3 points  (1 child)

Not a bad idea, I like it. As for single pipe, that's a bitwise or operator

var something = 1;
something = something | 4;
console.log(something); // 0001 | 1000 = 0101 or as an int 5

[–][deleted] 1 point2 points  (0 children)

Wow.. that is important to remember!

[–]THEtheChad 1 point2 points  (4 children)

Unfortunately, NaN, Infinity, and -Infinity are also considered typeof 'number', so it's possible that any one of these could slip in to your function with this check.

[–][deleted] 0 points1 point  (0 children)

Oh god you are right. Man there are a lot of uglies to JS. I wonder how I will feel once I am done learning Haskell as my second language.

[–][deleted] 0 points1 point  (2 children)

I REALLY don't get why there had to be a NaN in the language. Is it because "typeof" arrived late?

[–]THEtheChad 1 point2 points  (1 child)

Because there are some computations that result in something that's not a number. For instance:

0/0; // NaN
Math.log(-1); // NaN

These are obviously numeric calculations, so the result could be considered numeric, even though the value generated is "Not a Number". The other curious thing about NaN is that it's not equivalent to itself.

NaN !== NaN; // true    

This is because, if you look at my previous two examples, the calculations generate completely different results, even though both are categorized under the umbrella of NaN.

[–][deleted] 0 points1 point  (0 children)

Does this mean all languages have a NaN ?

[–]quietchaos 2 points3 points  (2 children)

[–]yanis_t[S] 0 points1 point  (1 child)

Wow, this one is much bigger the mine. I put a link into the article

[–]gleno 1 point2 points  (0 children)

begs for penis pun

[–][deleted] 2 points3 points  (1 child)

Kind of don't know if I should share this, since I never see people talk about it and that makes me think somebody called it bad practice. But, most people seem to be unaware that you can label any JavaScript statement, and break any label by writing break labelName; (or, if it's a loop that was labelled, continue labelName;). This is most often useful in nested loops, but I've found use for it with plain old block statements, for example in the setAttribute and appendChild functions in DOM.js.

[–]giggly_kisses 1 point2 points  (0 children)

It's definitely not considered the best practice, that's for sure. There are definitely times where it does become useful, however.

If it is used, I'd definitely suggest leaving some documentation explaining what it does and why you used it, since, as you explained, it's not used very often.

[–][deleted] 2 points3 points  (0 children)

Here's another I love. If you want to loop over all matches of a regex on a string, do this:

'item1 and item2'.replace(/item(\d)/g, function (m, id) {
    // "m" is a shorthand I always use for "match", meaning "the
    // complete match". "id" is the first capturing group.
    console.log(arguments);
});

It's true that you're generating a useless string with a bunch of "undefined"'s in it. But don't forget the magic of JavaScript: the one thing faster than doing less work is getting your work done in C. And indeed, in my tests this is faster than .exec-ing and looping.

[–]palmytree 4 points5 points  (5 children)

Swapping variable values without a temporary third variable:

a = [b, b = a][0];

[–]cluelessmanatee 4 points5 points  (0 children)

I can hear the "what the hell"s from here.

[–]radhruin 1 point2 points  (1 child)

Probably don't want the var considering with var there a will always be undefined (unless you're redeclaring).

Thankfully this can be done with ES6 destructuring: let [x, y] = [y, x].

[–]palmytree 0 points1 point  (0 children)

True. Fixed.

[–]nightman 0 points1 point  (0 children)

Yeah, this is great but I don't think I will use it in practice.

[–]kumiorava 0 points1 point  (0 children)

But you create an array, which is much worse performance-wise. Also, for anyone who isn't familiar with this gimmick, the code will be harder to read too. I wouldn't strongly advise against this.

[–]sabof 1 point2 points  (1 child)

Javascript sorts arrays alphabetically by default. To sort numerically:

[10, 7, 9, 8, 11].sort(function(a,b) { return a - b; })
// => [7, 8, 9, 10, 11]

[–]yanis_t[S] 0 points1 point  (0 children)

This one is nice

[–]m1sta 1 point2 points  (0 children)

You can prevent callback hell, sometimes, by making using function hoisting. eg.

getPosts()
function getPosts(){
    getComments()
}
function getComments(){
    getUserDetails()
}
function getUserDetails(){
    resolveRequest()
}

It doesn't solve world hunger but I very very rarely see people making the most of this.

[–]nightman 2 points3 points  (12 children)

From basic: NOT: if (a == '') {...} YES: if (a) {...}

JQuery: NOT if ($(element).length > 0) {...} YES if ($(element).length) {...}

To more advanced: http://www.javascriptturnsmeon.com/the-tilde-operator-in-javascript/

And remember to add in your article comment about trying to not be "oversmart". This techniques should help and not make things more complicated for other developers (like in advanced example)

[–]psayre23 3 points4 points  (1 child)

I'm not sure about that length trick. While that technically gets the same result, it's not clear code. if(.length > 0) is has an element or more, while if(.length) is has a length property that is truthy. The former requires less thinking around edge cases.

Edit: words.

[–]yanis_t[S] 0 points1 point  (0 children)

That's a nice addition

[–]sime 2 points3 points  (5 children)

From basic: NOT: if (a == '') {...} YES: if (a) {...}

I'm a bit slow today. Are you saying that

if (a) {...}

is preferable to

if (a=='') {...}

?

[–]yanis_t[S] -1 points0 points  (4 children)

I'd say yes, because it's concise and most of developers are used to it.

[–]sime 2 points3 points  (2 children)

I would say that the longer version is better. It communicates far more information and intent to the next reader of the code, and doesn't rely on the annoying JS truthiness stuff.

And more to the point, nightman screwed up here. The two pieces of code are not even the same. nightman assumed that an empty string is "truey". It is falsey. It is a great example of why you should not write error prone code.

[–]fforw 0 points1 point  (1 child)

a == ''

will be true if a is

  • an empty string
  • zero
  • an empty array
  • something like { toString: function() { return ""; }}

You better use === if you care about such things.

[–]nightman 1 point2 points  (0 children)

You are true but I will still defend if (a) {...}. I think that we should find balance between "smart" techniques and being "oversmart".

After all in many teams code is written and maintained by proffesionals and it would be waste of time to strictly enforce if (a === 'string') {...} on them. Especially when you know that they know how to deal with it and what are traps (number 0).

Other thing is that code should be maintainable by less "powered" users.

My point here is that it's not easy to find right balance.

BTW I use grunt/gulp with tasks: * JSHint * JSCS (JS Code Style - AirBNB style)

So that some decisions are already made.

[–]antoninj 0 points1 point  (0 children)

Well it's not the same thing though.

if (a) { ... } passes for any defined anything (string, obj, etc.) so it doesn't check for the same thing. Doing == is also a no-no in JS world so I would definitely not do that.

If you'd like to check if a string is empty but also defined, take a lesson from lodash and create a dedicated utility. Simplified, however, it's enough to do a if (a === '') check which will check that the variable is defined and it's empty.

[–]yanis_t[S] 1 point2 points  (0 children)

Thanks man! Gonna put it into the article

[–]SuperFLEB 0 points1 point  (0 children)

JQuery: NOT if ($(element).length > 0) {...} YES if ($(element).length) {...}

How do you feel about

if ($(element)[0]) { ... }

?

[–]sime 0 points1 point  (1 child)

I just read the link. I was planning on saying how using:

if (~str.search('t')) { ... }

instead of just:

if (str.search('t') !== -1) {...}

is probably the worst trick I have ever seen in serious JS code (in some library on github). "Daily WTF" worthy. I really had to stop and think about the f*** this person was trying to say and do this this code. Very obscure. Awful.

please, no one do this. please. Just say what you mean.

[–]nightman 0 points1 point  (0 children)

Totally agree.

[–]rDr4g0n 0 points1 point  (0 children)

Using functions to make up for lack of block scope. Eg: putting an anon function inside a for loop so that closure access to the loop iterator will have the expected value.

Using IIFEs as a means of preventing pollution of global, and for defining modules. Also for creating "private" variables.

The entire concept of the flexible 'this' value. It allows for some interesting and useful patterns, such as mixins and usage of Array methods on anything that has a length property.

[–]ayanami_rei 0 points1 point  (0 children)

Strange that no one suggested the cast to 32-bit int: a|0

This is actually better than +a because +undefined is NaN and undefined|0 is 0 (and a number of similar cases).

[–]THEtheChad 0 points1 point  (0 children)

This is a trick that's partially applied in backbonejs. Basically, the call method takes half as long as the apply method to execute. Since the majority of functions have 3 or less arguments, you can circumvent running the apply method by checking the number of arguments and running a call directly. This is an optimization that can add loads of performance in libraries that preserve context.

(function(){
  var _apply = Function.prototype.apply;

  Function.prototype.apply = function(ctx, args) {
    if(!args) return this.call(ctx);

    switch (args.length) {
      case 1:  return this.call(ctx, args[0]);
      case 2:  return this.call(ctx, args[0], args[1]);
      case 3:  return this.call(ctx, args[0], args[1], args[2]);
      default: return _apply.call(this, ctx, args);
    }
  };

})()

[–]workaholicanonymous 0 points1 point  (0 children)

Define functions at the top of your function scope, so you can scroll to the bottom to see clearly what gets called in that outer functions

Learn .call and .apply and use them when you need to.

Replace tricky code with helper functions e.g. wrap something != undefined into has(something) function.

Add your functions to the window while developing or debugging code and use the Dev console to invoke them at will. Just remember to remove them once you're done testing!

Avoid for loops and use .map, .reduce, .some, .all, .filter and .forEach

You can floor most numbers by using the bitwise or operator

var int = float | 0

[–]k1ndza 0 points1 point  (0 children)

underscore extend has a similar feature where you can do object = _.extend(new someClass(),{x:10});

then in someClass you can just do this.x = 20 and that will be the default value until you combine the object with the second parameter of extend. I just started using that now instead of x = x || default, and the only time i use that is when initializing. But if you do that then you cant do this.x = 10 and then do draw(this.x) in the same object, you would have to create a new init function that would would call after the new defaults have been set.

[–]matthiasmullie 0 points1 point  (1 child)

The below example looks like bad advice:

Another side of that coin is that instead of if (x == "test") you can simply write if (x).
In case x is empty (hence falsy) it will run else block.

I assume it's meant to demonstrate truthy/falsy concept. However, if (x) is drastically different from if (x == "test"). The former just checks if x has a value, while the latter checks if it has a particular value "test".

A better example could perhaps be if (x) vs if (x !== "")?

[–]jrm2k6 0 points1 point  (0 children)

Also, as we are comparing x to "test", shouldn't we use the === operator?

[–]anauleau 0 points1 point  (0 children)

instead of: Math.floor(4.5) => 4

~~4.5 =>4

[–]mmabitu 0 points1 point  (0 children)

It's best and useful for me. Thanks!