32 comments

[ 3.4 ms ] story [ 74.9 ms ] thread
I kinda hope I never have to debug or modify any code written by a person who writes javascript like this.
2, 3, 4 should not be done.

There is no value in using any of those features.

As mentioned, 5 is not a thing. That's spec politics, you shouldn't be doing any of that.

As for 1, well that's a whole other argument, and it's an opinion. You choose one, nobody cares what you choose.

I will then chime in that #5 isn't even a thing (it seems to be a continuation of the argument from #4)...
Doesn't `with` have significant runtime costs? I didn't think people didn't like that one because it was a 'bad pattern' - I thought it was because it was really slow.

EDIT: I went ahead and JSPerf'd it, and it is 13x slower to run the example in the article.

http://jsperf.com/with-perf

A lot of times this doesn't matter, but it's not nothing.

Edit 2: Also people avoid using `with` so their minification tools have a better chance. Another thing that can be overcome, but just pointing out that it's not religious dogma that makes people avoid `with`.

I wouldn't use "with" in most situations, but I like it in the testing code and for some DSLs, as it makes things more readable (again, personal style).

I think that once you start optimizing performance problems you need to 1) measure things anyway, and 2) fix on a case-by-case basis. (Don't optimize prematurely, etc.)

In addition I'd say that the interpreter is broken and should be fixed to be faster. "with" is not deprecated.
I don't believe that this is just an oversight because "people say you shouldn't use `with`". It simply cannot be optimized in the way that normal property accessors are. If you look at old IE perf, they're actually pretty close (both really slow).
The trouble with armchair quarterbacking is that many things are easier said than done. It's not like they're deliberately making your code slower — the with-statement makes certain optimizations unfeasible. Their options are to always disable those optimizations or to do it only when there's a with-statement in scope — there's no third option that makes with-statements magically fast. If you can come up with new optimizations that make the with-statement faster, I doubt they'd turn down your patch.
I've always regarded JS as a DWTFYWL (Do What The Fuck You Like Language). With Google's Closure Compiler, all your useless statements about 'thou shalt not use' are redundant.

If people want to save bytes, they will do it naturally. Everyone has their own coding style. Enforcing 'your way' on others is just patronizing, and shows how little regard you have for others carefully crafted workflow. Sure, avoiding the Wrath of Crockford is fine, and I demand every developer adheres to his always useful comments on the language.

But don't try and be him, by offering very little in depth advice on what 'not to do' in JS. The only people that avoid semicolon use are the ones writing JS1K demos, and actually care about bytes. The rest - they do it to save costs on their high-speed CDN setups they have on their blog.

My point is, there is no need to be religious when we already have a dozen or so packer scripts, and byte-saving scripts, on the web already (JSCrush, Dean Edward's Packer Tool, @cowboy's packify etc.)

Not to mention the already mentioned, and very powerful Closure Compiler. And I could go on, and I urge others to suggest other packers out there at the moment in this discussion.

When I'm hit by a bus, and my code is only understandable by me, then sure, by all means, attack me, and mark my code as obsolete, unusable, and redundant, but at least look through the foot-notes and see I made a developer-friendly version of my code, completely un-minified, obfuscation free, and free of gotchas and unorthodox methods.

Peace.

http://higg.in/s/

The reason features like 'with' and callee are being pushed out of JS is because they are a complete nightmare for JS engine optimizations. Doesn't mean they are not useful for certain (hacky) things. Google Dart is a direct response of the V8 team against JS having (among many other things) these kind of constructs. If you want your JS to keep getting faster, try not frustrating the guys that make your crap code faster by advertising these constructs too much. Thank you.
And this behavior is totally obvious (not)

  var id = 123;
  function updateOptionalProperty(obj) {
    with (obj) {
      id = 456;
    }
  }

  updateOptionalProperty({id: 0});
  id // 123

  updateOptionalProperty({});
  id // 456
I actually ran into code once that had a variable named "position" (totally common name) and then used "with" on a node's style property to set another style based on the value of this "position" variable. Instant bug. It took me a while to figure out what was going on.
I'll say that I disagree with just about every point made here and certainly not because of some religious fervor. I won't enumerate them all, and I completely refuse to get drawn into the debate of semicolons vs. no semicolons; but statements like this,

"Whether you like it or not, whitespace is significant in JavaScript. A linebreak indicates, in most cases, the end of a statement; a semicolon is automatically inserted for you."

Are just flat out absurd. Like it or not, automatic semicolon insertion is NOT significant whitespace and the second sentence completely contradicts the first by pointing out that ASI happens in MOST cases--but not all. If whitespace were truly significant, it would apply in ALL cases. Again, I'm not debating whether you should use semicolons or not--but I'm willing to flat out state that Javascript does not have significant whitespace; no matter how you want to spin it.

That said (and now here comes the "someone had to say it department") this strikes me, yet again, as Thomas being contrarian for the sake of getting a rise out of folks to draw attention to himself. I mean no disrespect with this statement; but anyone who has followed him for a long time on Twitter knows that he's apt to taking an unpopular position and leveraging it as a marketing opportunity for himself (and, by extension, his consulting and training enterprises). That's a fine approach; but, I felt it time someone identified it for what it is. Thomas is a smart dude and he's built some amazing things; but his public persona and style is carefully crafted and contrarian and we're all buying in by popularizing the debates he either creates or catalyzes.

[Edit: fixed a typo]

Whitespace is significant sometimes, and not other times. That's the fact of the language design/ASI itself, not Thomas being contrary.

As to this:

leveraging it as a marketing opportunity for himself (and, by extension, his consulting and training enterprises)

Thomas doesn't consult any more, and hasn't for years, and we have almost entirely discontinued our training workshops, because they are too much work. However, when we want some extra cash and put one on, they sell out regardless of what we say or do, because Thomas' real life JavaScript experience (crafting amazing libraries which jumpstarted the dynamic web, used by millions) and my real life teaching experience speak for themselves.

Yours is a fallacious argument.

Your entirely predictable defense of your husband notwithstanding; I don't mean to diminish Thomas's contributions to the Javascript community at large nor the quality of the work he does. I hope I made that point entirely clear in my original post (and if I hadn't, I hope I am doing so now). I call it how I see it; and I see no need to repeat myself as to why I believe what I posted. Attempting to call my argument fallacious with absolutely no justification other than correcting one minor (and somewhat irrelevant given that self-marketing is important regardless of one's current occupation) incongruity is little more than an attempt to drag me into a 2-on-1 battle royal in which I refuse to participate.
You spent 47% of your words in your comment on that paragraph because "somebody had to say it", and it was incorrect. Is 50% of what you write being incorrect a "minor" issue?

And as for my entirely predictable defense of my husband… anyone who's watched us work together would laugh at that statement. But in this case, he's right, and you barely mounted an argument except that:

"Whitespace isn't significant" -- except that, of course, by ASI rules, it is sometimes and not others. You can argue over the meaning of the word "significant" and say it is all or nothing, but that is not what the rules of ASI indicate. Call it what you will -- sometimes it is, sometimes it isn't.

"This is a calculated marketer at work, trying to sell consulting and training" -- which is untrue.

As for my comment being "little more than an attempt to drag me into a 2-on-1 battle royal" -- is Thomas even addressing you? Not at all, from what I can see.

Only responding to clarify: the only part I will admit was incorrect was the quote, "and, by extension, his consulting and training enterprises." Everything else I said I stand by 100%. Maybe I'm wrong and that's not his intent--but it's certainly the perception I have; having watched this same scene play out time and again.
Your whole argument about him doing this for promotional purposes hinges on the idea that he gets something out of it (e.g. sales). You have no real reason to believe that he takes a "contrarian" position to "get a rise out of others," other than your implication that he gains by "marketing opportunities."

In fact, your whole argument was a subtle way of saying "He doesn't really believe this, he's just peddling shit in order to make sales." None of which you can support, especially since the implied gain (the sales) doesn't exist.

You have no real reason to believe, much less state publicly, that Thomas is disingenuous in his opinions.

This makes it an ad hominem attack, by the by.

>but statements like this,

>"Whether you like it or not, whitespace is significant in JavaScript. A linebreak indicates, in most cases, the end of a statement; a semicolon is automatically inserted for you."

>Are just flat out absurd. Like it or not, automatic semicolon insertion is NOT significant whitespace and the second sentence completely contradicts the first by pointing out that ASI happens in MOST cases--but not all. If whitespace were truly significant, it would apply in ALL cases.

I don't mean to gang up on you, but that just isn't right. Will you agree that newlines are significant in both Ruby and Python? Because both of those have cases where newlines are not terminal. So I think this absolutist stance is quite unreasonable.

Automatic semicolon insertion is ipso facto indistinguishable from significant newlines in a language where semicolons are statement terminators — both mean that you can end statements with newlines. The fact that JavaScript's ASI rules have awkward holes just means that its ASI rules have awkward holes. Have a look at Go for an ASI language whose creators take the opposite stance of Eich's — even though semicolons are canonically there at the end of statements, you're encouraged to omit them in your code.

Basically, I think you're taking a far stronger stance than is warranted. I don't agree with a lot of what Thomas Fuchs said in the OP, but let's not try to outdo him in absurdity. You can feel that including semicolons is the right choice without ignoring the plain fact that ASI does mean you can end statements with newlines most of the time (and that the inability to do so in a few edge cases does not prove otherwise).

This is all spectacularly bad advice. Some of it is actually just false.

> A linebreak indicates, in most cases, the end of a statement; a semicolon is automatically inserted for you.

These are weasel words. Either a line break is the end of a statement or it's not. In JavaScript it is not.

> In order to be able to write properly working code, you need to be aware of the rules of Automatic Semicolon Insertion, regardless if you choose to add semicolons at the end of lines or not.

You absolutely do not. I don't care if you use semicolons or not, but don't claim that knowledge of ASI is required to write good JavaScript.

> Fix problems when you actually have them. Use the time you’ve freed up by not prematurely optimizing and spend it with your family or have a holiday on the beach.

Using deprecated features like __proto__ and arguments.callee is not something that you can trivially fix later. These are advanced features and I can't think of an easy why to duplicate their behavior once they are gone. You're going to have to rewrite a significant chunk of your code. Please never, ever use these features in libraries that are shared with other developers.

> Please never, ever write libraries that are shared with other developers.

FTFY

> These are weasel words.

No, actually, that's how it works in JS. ASI doesn't "work" in all cases because a line break doesn't always indicate the end of a statement. No less than Brendan Eich wrote this himself, in his blog post reply to the whole "semicolongate" which happened a couple weeks ago.

I'm sure it feels good to be all righteously angry… but it helps to be right.

http://www.thefreedictionary.com/weasel+word

> Weasel word: An equivocal word used to deprive a statement of its force or to evade a direct commitment.

From the article, emphasis mine:

> A linebreak indicates, in most cases, the end of a statement;

That's like saying that "Car crashes, in most cases, are not fatal" is weasel words at work, when in fact it's simply a fact. Car crashes are not fatal, in most cases. And in JS, a line break indicates the end of a statement, in most cases. It's in the spec for ASI.
I'm personally getting bored of hearing about semi-colons in javascript.

But #4 rubs me the wrong way. This strikes me as the opposite way to spend more time with your family. A little bit of preventative effort done on the clock will often reduce the amount of emergency code fixes that you do after-hours.

I think people are missing the main points of the article - so here they are again:

"Or, don’t trust what “wise” elders tell you."

"My recommendation: learn the language, and use it to your liking; and don’t rely or blindly accept what any “wise elders” tell you. Try to do something new and crazy every day. You might not end up using the crazy, but it’s the best way to master JavaScript. Develop your own style that you are comfortable with. Experiment."

these points are still up for argument, but really they are pretty trivial. __You__ should __experiment__ with them and see if they are okay to use for yourself. The main trick will be if they make your code easier to understand and/or perform better _everywhere_. As long as it helps one of those cases without the detriment of the other then go ahead, just be aware of why people argue over them.

If that's all he had said, there wouldn't be so much pushback. But instead, he's setting himself up as a "wise" elder dispensing advice, and (ironically) much of what he's said is wrong.

If his point two was, for example: "You should always test received wisdom. You've probably heard not to use 'with', but do you know why? Well, let's write a quick benchmark, here's some code with 'with' and here's some without. And if we benchmark it like so...hey look! The code with 'with' is a little clearer, but it's glacially slow! And now you know not just why and when to avoid 'with', but how to test other language features too!"

But instead, basically, he said "Hey, don't listen to those idiots who say not to use 'with', listen to me! And I say it's awesome!" This is unhelpful on multiple levels.