TE
科技回声
首页24小时热榜最新最佳问答展示工作
GitHubTwitter
首页

科技回声

基于 Next.js 构建的科技新闻平台,提供全球科技新闻和讨论内容。

GitHubTwitter

首页

首页最新最佳问答展示工作

资源链接

HackerNews API原版 HackerNewsNext.js

© 2025 科技回声. 版权所有。

JavaScript: Warts and workarounds

117 点作者 fogus超过 13 年前

12 条评论

jashkenas超过 13 年前
For the record, CoffeeScript tries to help ameliorate <i>all</i> of these "warts".<p>* "Hoisting under the hood" -- Function declarations vs. function expressions don't get you into hoisting trouble, because there are no function declarations, and every value is an expression.<p>* Explicit block scopes can be (more easily) created with:<p><pre><code> do (x, y) -&#62; # here, x and y are captured in a new scope. </code></pre> * "What does 'this' mean?" -- The value of "this" can be fixed lexically, by using the bound function (fat arrow) =&#62;, instead of the normal function arrow: -&#62;. Look ma, no "var that" or "var self":<p><pre><code> $.getJSON url, (resp) =&#62; this.setResponse resp </code></pre> * "Fixing Arguments" -- Function arguments are always available as an array instead of an Arguments object.<p><pre><code> myVariadicFunction = (args...) -&#62; # here, "args" is an Array. </code></pre> * "Avoiding truthiness" -- There is no "==" and "!=" in CoffeeScript, all equality is strict equality. For the one case where double equals <i>is</i> useful in JS, you have the existential operator...<p><pre><code> if a is b # here, a === b.</code></pre>
dherman超过 13 年前
I'm a friend of Matt's, and I enjoy his blog posts, but I'm afraid this post is full of bad advice and misinformation. He claims that `with` followed by an object literal is fully statically analyzable (it's not, because of prototypes), and he recommends using it without considering how badly it deoptimizes in all modern JS engines.<p>And spicyj is right that NaN is not equal to itself in most languages because that's how IEEE754 specifies it. In particular, this is true in Scheme, one of Matt's favorite languages. ;-P<p>(Also, depending on what he means by "true equality," his `equal` function fails to distinguish -0 and 0, which are distinct values in the language. However, I suspect those are best treated as the same value. It's extremely rare to want to treat -0 as if it exists at all.)
spicyj超过 13 年前
<i>Yet, there is still a value x such that x != x and x !== x.</i><p><i>That value is NaN.</i><p><i>If true equality matters, use a helper function:</i><p><pre><code> function equal(a, b) { if (a === b) return true ; if (isNaN(a) &#38;&#38; isNaN(b)) return true ; return false } </code></pre> People keep repeating this as a strangeness of JavaScript, whereas in fact this is standard floating-point behavior, the same as you'll see in any other language (C, Java, Python, really everything). In JavaScript, you almost always just want a === b, not a function that checks for NaN.
评论 #3591163 未加载
评论 #3591352 未加载
finnw超过 13 年前
The first code sample in the article is wrong:<p>&#62; <i>In most curly-braced languages, blocks delineate lexical scope. For example, in C or Java:</i><p><pre><code> { int i = 13 ; { int i = 42 ; print(i) ; } print(i) ; } </code></pre> In fact this will not compile in Java.
评论 #3592071 未加载
spicyj超过 13 年前
One of the strangest things about == is that although it's commutative, it's not transitive:<p><pre><code> 0 == '0' // true 0 == '' // true '0' == '' // false</code></pre>
评论 #3592567 未加载
greggman超过 13 年前
Honestly, I don't agree that most of these are warts. In particular function scoping vs block scoping, get THE F over it. Gees.<p>Sure when I first started JavaScript it bit me exactly once. Since then, I got use to it. It's a different language, every language has its quirks. I'm sure if you started with JavaScript the fact that many other languages DON'T have block scope might upset you. You know what else doesn't have block scope? PYTHON!<p><pre><code> def foo(): if True: x = 123 print x </code></pre> prints 123. In C, Java, C++ you'd get an error that x doesn't exist.<p><pre><code> void foo() { if (true) int x = 123 printf("%d\n", x); } error: ‘x’ was not declared in this scope </code></pre> 4 meanings of this?<p>The fact is it gives you huge flexibility. By default, lots of libraries add names to the global object (for browsers that's 'window') but because you can control 'this' for all functions you can force any library to install itself to some other object.<p>Can you do that in C, C++ or Java? As far as I know the only way to fix that in those languages is to edit a bazillion source files and change namespaces of you're lucky enough to have them.<p>Truthiness?<p>Again it's just different not broken. Lots of dynamic languages have strange kinds of conversions. Learn them and get over it. The only people this messes up are people expecting it to behave like Java or C/C++. It's not Java or C++. It's not JavaScript's fault you're too stubborn or set in your ways to try it a different way.
ax超过 13 年前
1. Don't use with. It's hard to reason about, and it breaks many compiler optimizations (you're adding a dynamic object into the scope chain).<p>2. Just don't ever use == or !=. Forget they exist. Done.
评论 #3591173 未加载
评论 #3591155 未加载
评论 #3591408 未加载
jayferd超过 13 年前
It's also impossible to instantiate an object with `new` and varargs.<p><pre><code> new Breakfast('bacon', 'eggs') // great new Breakfast.apply(null, ['bacon', 'eggs']) // b0rk</code></pre>
评论 #3591292 未加载
评论 #3591020 未加载
评论 #3590944 未加载
mistercow超过 13 年前
That use of `with` makes me squeamish as hell.<p>Also, on the topic of the "eta" function, it's odd that the author seems unaware of existing implementations of `bind`.
评论 #3590811 未加载
underwater超过 13 年前
<i>The way around this scoping issue is to declare `that`.</i><p>It's simpler to bind the function to the current object. <a href="https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind" rel="nofollow">https://developer.mozilla.org/en/JavaScript/Reference/Global...</a>
firefoxman1超过 13 年前
Something sort of random I just noticed: you can wrap stuff in {} to make blocks without an actual block statement...just a random block of code. That may be pretty useful once the <i>let</i> keyword becomes widely available, and could be used now to maybe organize lots of code?
评论 #3590813 未加载
评论 #3590861 未加载
adambard超过 13 年前
My rule of thumb is, as soon as it gets to the point where I need to use "this", I find a library that abstracts that whole business away.<p>I've been there and it sucks. I say leave it to someone with the expertise to use "this" in Javascript without shooting themselves in both feet, at least for browser-side work.
评论 #3590971 未加载