If you wanted to find a friend for someone would you keep trying to introduce them to same stupid ugly person, while saying: "Look! He/she is wearing make-up this time!".
Whether you like it or not js is here to stay. It's the language of the web (and more). A lot of new capabilities are being exposed via browser makers (e.g peerconnection, webrtc) which only serve to increase its power. Calling it stupid and ugly is your unsubstantiated opinion. (Infinitely more useful: say why this is your opinion.)
I think this is a nice intro to the language. Why it's being posted now though is a little puzzling considering it's from 2006. It is obviously still relevant and interesting but readers should realize it's not very recent.
Thank you, although please note that "JavaScript Spessore" is (a) a work-in-progress, and (b) about "Thinking in objects" more than "The idiomatic way to program in JavaScript.
> js is here to stay. It's the language of the web
In the same manner as assembler is here to stay. Assembler is "the language of the computer". Not that many people write assembler these days though, majority moved on to languages more suited to their needs.
"Hey, look, this is Jenna. You'll have to work with her for the next 10 years. She's hard to figure out and grumpy at times, but if you treat her right she'll play along. Actually if you get to know her, she can be a great asset."
Please stop blaming users. If Jenna is a royal pain in the ass by design, her being a pain in the ass isn't the user's fault for not "treating her right." Whether it is an asset to work around her crap or not. There's all kinds of things which are an asset to know but are a huge pain in the ass to work with, and somehow we are allowed to complain about most of those but god help the man who complains about Jenna in public. She's connected.
Paul Graham once said, "Where there's muck, there's brass." He explained that there is often an opportunity to be had if you dive deep down into ugly, unpleasant things and find a way to make them work.
“Everything that can be written in JavaScript will eventually be written in JavaScript”. – Atwood’s law
"Everything’s Gone JavaScript"
"The future is written in Javascript"
JavaScript is now an integral part of several operating systems.
JavaScript is also moving quickly into the hardware world.
typeof null returns "object", but I do not believe it is correct to claim that null "is an object". It is my understanding (maybe a misunderstanding, I will happily state) from reading a ton of comments from Brendan Eich in various places that typeof null is "object" for historical reasons involving the way reference types were implemented in the original JavaScript VM.
It is correct to say that typeof(null) returns the string 'object' because of a bug that is now written into the standard to prevent old software from "breaking" if they fixed this.
It is not ever correct to say that null in JavaScript is an object. Just ask javaScript itself:
Object.getPrototypeOf(null)
//=> TypeError: Object.getPrototypeOf called on non-object
That's a mistake in the specification. We tried to fix that experimentally but it broke too many sites.
If you check the language specification you can see that `null` is in fact not an object - it's something called a 'primitive value type', just like numbers, strings, undefined and booleans.
Along the way, autoboxing will convert a string to an object delegating to String.prototype if you write something like "hello".foobar(). But primitive value strings are not objects.
No. It's not a good introduction to JS. JS is very WTF worthy (I should know, I'm writing a book on how to write asshole Javascript), but the WAT talk is NOT a good intro
Agreed, it's a collection of trivia. Very WTF-worthy trivia but if your code is doing basically any of the things listed in that talk, something has gone terribly awry.
If you truly want to master the language, Reg Braithwaite's stuff is incredible. I think Javascript Allongé is one of the best programming books I've read on any topic, and it's free online: http://leanpub.com/javascript-allonge.
Crockford is largely how I learned too. He's a crank but I've found that to be a useful property when I was learning JS. (Or really, re-learning it as you say)
Off-topic, but I must say that this site handles resizing very well. I really appreciate it when a website seamlessly transitions from desktop-size to mobile-size layout. Sometimes I just like having my browser window shrunk down (or zoomed in for viewing from farther away), which means that with most sites I have to scroll horizontally, which is not very usable.
There's Dynatrace, IESieve and Drip (the latter two's websites are now defuct though), but IIRC, the IE team fixed the memory leak issue via a service pack or hotfix a few years ago.
The "even nicer [array for loop] idiom" is pretty cool:
for (var key = 0, value; value = someArray[key++];) {
// value is already defined by for loop
console.log('index: ' + key, 'value: ' + value);
}
Also, I finally understand closures:
"Whenever JavaScript executes a function, a 'scope' object is created to hold the local variables created within that function. It is initialised with any variables passed in as function parameters. This is similar to the global object that all global variables and functions live in, but with a couple of important differences: firstly, a brand new scope object is created every time a function starts executing, and secondly, unlike the global object (which in browsers is accessible as window) these scope objects cannot be directly accessed from your JavaScript code... A closure is the combination of a function and the scope object in which it was created."
Note that this trick should only be used
for arrays which you know do not contain
"falsy" values (arrays of objects or DOM
nodes for example). If you are iterating
over numeric data that might include a 0
or string data that might include the
empty string you should use the i, len
idiom instead.
You're correct. Seems like a pretty useless/dangerous idiom to me. How often can you be sure that in 100% of cases your loop will never iterate a 0, an empty string or some other falsey value?
That was a great way to iterate over a non-sparse array such as an array of objects... Back in 2006 when this article was written.
In fact, this was an even better way to write that loop in 2006:
for( var value, i = -1; value = array[++i]; ) {
console.log( 'index: ' + i, 'value: ' + value );
}
Basically the same thing except for the pre-increment instead of postincrement. In some of the browsers of that day (at least IE), preincrement was faster. And this version gives you the correct array index inside the loop, unlike the off-by-one in the other version.
I was so proud of myself when I discovered this alternative that I wrote a recipe for the jQuery Cookbook recommending it as the fastest way to iterate over a typical array of objects such as you might receive from a JSON request.
It also used to be a great idea to optimize your machine code programs by looking up the CPU cycles for each instruction. Fewer cycles = faster code.
Of course, that doesn't work any more, what with pipelining and out-of-order execution.
Alas, these nifty JavaScript loops are not the fastest any more either. Fewer operations != faster code.
The optimization guy for V8 explained this to me at Google I/O 2012. He said that V8 can optimize the heck out of references into an array where all the types are the same (either primitive values, or objects that all have the same properties). But if you ever try to reference outside the bounds of the array, it throws the whole thing back into deoptimized code.
And that is the problem. These nifty loops rely on reading the nonexistent element just past the end of the array. That's their termination condition.
It turns out that with modern optimizing compilers, the plain old traditional JavaScript loop is faster across the board:
for( var i = 0, n = array.length; i < n; ++i ) {
var value = array[i];
console.log( 'index: ' + i, 'value: ' + value );
}
(There is still a minor benefit to using preincrement instead of the more traditional postincrement in some modern browsers.)
>I was quite embarrassed to learn how poorly my clever loop works in modern browsers!
What's really embarrassing is IE js performance.
Since I keep an ancient copy of of Netscape 9.0.0.6 on my computer I decided to try it so see how much browsers have improved. It doesn't seem to upload results I'll post them here in the same order as the testing page.
17.25
16.72
5.94
8.81
18.90
23.28
20.92
23.58
This is on the same computer that was pulling 5000+ on the fastest tests. Browsers have come a long way.
Small problem with the conditional using the array assigment. If a value in the array is not "truthy", the loop will stop at that element -- e.g. ['a', 0, 'b', 'c'] will only print out the first element in your example.
"It was originally going to be called LiveScript, but was renamed in an ill-fated marketing decision to try to capitalize on the popularity of Sun Microsystem's Java language "
I've read this article a couple of times in the last few years and it never ceases to amaze me. Clearly and in a concise way it lists all the points that people usually miss about JS.
"We've introduced another keyword: 'new'. new is strongly related to 'this'. What it does is it creates a brand new empty object, and then calls the function specified, with 'this' set to that new object"
Perhaps it would be worth to mention that 'new' not only sets 'this' to be the empty object but also return that object to the location where new was used.
73 comments
[ 2.5 ms ] story [ 144 ms ] threadWhether you like it or not js is here to stay. It's the language of the web (and more). A lot of new capabilities are being exposed via browser makers (e.g peerconnection, webrtc) which only serve to increase its power. Calling it stupid and ugly is your unsubstantiated opinion. (Infinitely more useful: say why this is your opinion.)
I think this is a nice intro to the language. Why it's being posted now though is a little puzzling considering it's from 2006. It is obviously still relevant and interesting but readers should realize it's not very recent.
* Overview: https://rawgithub.com/whatwg/html-differences/master/Overvie...
The next thing is JavaScript "next" or Ecma Script 6
* http://wiki.ecmascript.org/doku.php?id=harmony:proposals
You can use Traceur if you want to try out ES6 features today More info: https://github.com/google/traceur-compiler
These days there is a lot of things going on in the tooling section
Build: * Grunt: http://gruntjs.com/ - a lot of grunt- tasks at http://npmjs.org/ * Newest kid in town: https://github.com/gulpjs/gulp
Modulization and dependency management: * http://en.wikipedia.org/wiki/CommonJS * http://browserify.org/
https://leanpub.com/javascript-spessore
In the same manner as assembler is here to stay. Assembler is "the language of the computer". Not that many people write assembler these days though, majority moved on to languages more suited to their needs.
"Hey, look, this is Jenna. You'll have to work with her for the next 10 years. She's hard to figure out and grumpy at times, but if you treat her right she'll play along. Actually if you get to know her, she can be a great asset."
"Don’t make idols for yourselves" is another old expression.
It is not ever correct to say that null in JavaScript is an object. Just ask javaScript itself:
If you check the language specification you can see that `null` is in fact not an object - it's something called a 'primitive value type', just like numbers, strings, undefined and booleans.
Here http://es5.github.io/#x8 :)
> There's our first brush with JavaScript objects! Did I mention that strings are objects too? They have methods as well
Also, how do NaN and infinity fit in? I'm guessing they're special cases of Number types?
- NaN is just a number type . You have NaN in Java or C++ too. It's a way to represent "a number we can't represent"
- Good catch on strings, I'll edit it in.
Those are magical values from IEEE 754.
IEEE 754 is also the reason why there is a signed zero or why division by zero results in +/- Infinity.
Along the way, autoboxing will convert a string to an object delegating to String.prototype if you write something like "hello".foobar(). But primitive value strings are not objects.
https://www.youtube.com/watch?v=v2ifWcnQs6M#t=489
1. https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re...
Edit: Just noticed inglor say it was a caching issue and the page was updated today.
Maybe remove the "2006" from the headline (again).
https://www.destroyallsoftware.com/talks/wat
(with a little bit of ruby)
1. Douglas Crockford videos: http://www.yuiblog.com/crockford/
2. Eloquent JavaScript intermediate level tutorials: http://eloquentjavascript.net/contents.html
[1] http://effectivejs.com/
One question though, it says:
a.push() variant seems more elegant to me. Why is a[] variant "safer"?https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
So, why should a[a.length] be safer?
"Whenever JavaScript executes a function, a 'scope' object is created to hold the local variables created within that function. It is initialised with any variables passed in as function parameters. This is similar to the global object that all global variables and functions live in, but with a couple of important differences: firstly, a brand new scope object is created every time a function starts executing, and secondly, unlike the global object (which in browsers is accessible as window) these scope objects cannot be directly accessed from your JavaScript code... A closure is the combination of a function and the scope object in which it was created."
Given that the loop also fails to complete if someArray contains a falsy value, I'd say this trick falls into the "too cute to be safe" category.
In fact, this was an even better way to write that loop in 2006:
Basically the same thing except for the pre-increment instead of postincrement. In some of the browsers of that day (at least IE), preincrement was faster. And this version gives you the correct array index inside the loop, unlike the off-by-one in the other version.I was so proud of myself when I discovered this alternative that I wrote a recipe for the jQuery Cookbook recommending it as the fastest way to iterate over a typical array of objects such as you might receive from a JSON request.
It also used to be a great idea to optimize your machine code programs by looking up the CPU cycles for each instruction. Fewer cycles = faster code.
Of course, that doesn't work any more, what with pipelining and out-of-order execution.
Alas, these nifty JavaScript loops are not the fastest any more either. Fewer operations != faster code.
The optimization guy for V8 explained this to me at Google I/O 2012. He said that V8 can optimize the heck out of references into an array where all the types are the same (either primitive values, or objects that all have the same properties). But if you ever try to reference outside the bounds of the array, it throws the whole thing back into deoptimized code.
And that is the problem. These nifty loops rely on reading the nonexistent element just past the end of the array. That's their termination condition.
It turns out that with modern optimizing compilers, the plain old traditional JavaScript loop is faster across the board:
(There is still a minor benefit to using preincrement instead of the more traditional postincrement in some modern browsers.)I put together a JSPerf for this a while ago:
http://jsperf.com/mikes-loops/2
I was quite embarrassed to learn how poorly my clever loop works in modern browsers!
What's really embarrassing is IE js performance.
Since I keep an ancient copy of of Netscape 9.0.0.6 on my computer I decided to try it so see how much browsers have improved. It doesn't seem to upload results I'll post them here in the same order as the testing page.
17.25 16.72 5.94 8.81 18.90 23.28 20.92 23.58
This is on the same computer that was pulling 5000+ on the fastest tests. Browsers have come a long way.
It is frequently and recently updated.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re...
Perhaps you should add your bit?
1. Crockford's C style with cached array length (fast and flexible, but verbose):
2. Functional style (terse and flexible, but slow): 3. Python style (fast and terse, but not flexible): By "flexible" I mean being able to e.g. iterate over items with odd indexes or in reverse direction.Uh, how floating poing operators are different than this in C or java
Perhaps it would be worth to mention that 'new' not only sets 'this' to be the empty object but also return that object to the location where new was used.