Excellent write-up! I've learned most of these things the hard way :/ I'm filing this away to recommend to any developers who are setting out to use Javascript extensively for the first time.
One quibble: In the "common pitfalls" section regarding the "this" object, they say that locally-defined functions within other functions never have any practical use. I might disagree: with a little coaxing, you can convince locally variables inside the constructor (both functions and other variables) to serve as private properties of an object; this is the only technique I know that allows for private properties.
(I haven't actually done this in code that has been maintained/used anywhere, I just did it as an experiment and filed it away as a "that's cool" for future reference)
> One quibble: In the "common pitfalls" section regarding the "this" object, they say that locally-defined functions within other functions never have any practical use.
Might also come in handy if you are into functional programming with Javascript.
There is actually a much better way to make private functions and properties in JavaScript using the module pattern and closure.
Since all functions are objects in JS, you can create a function with some internal (private) functions and properties than return a object with some publicly accessible functions. A basic example:
Closure gives you a really powerful structure that lets you encapsulate your code and then you don't have to use this and risk clobbering the global window object :)
Be careful of that. There is a trap right there. Your example is using the "new" keyword and not executing the function. So what happened?
1. If you use the "new" keyword, and don't execute the function. "x = new foo()". X becomes an "object". "foo()" is behaving like a class. You got to define the properties and methods of this class with the "this" keyword. Once you create your object with the "new" keyword, these variables got assigned to the object. And better, you can access them with the prototype.
2. If you execute the function in your code, that is you put "foo()": Open your FireFox with FireBug and notice two new global variables in the Windows object "get_my_private" and "set_my_private".
So it depends on the usage. "this" insides of a function is useful, if your intent is to use the function as a class. If not, it's dangerous, as the variables becomes global and may interfere with other variables.
It's a great book but one has to note that not everything there is "how things should be done" these days, Crockford himself has changed his mind on some of the things he wrote there. Take this as for example: http://www.bolinfest.com/javascript/inheritance.php or that the book advocates extending native objects (including "Object").
So when you create a new instance of Bar, it's constructor still appears to be Foo even though it really isn't. Setting the prototype.constructor fixes that.
I think it's more of an issue of who is doing the extending. If it's your own code in a non shared library, then it's up to you.
If it's in a shared library, it is probably nicer to avoid. For instance, if you override a function on a native prototype, you might be overwriting some future function that browsers will implement. I've seen this done with Array.map for instance.
If somebody’s wondering about the double dot like me: “A common misconception is that number literals cannot be used as objects. That is because a flaw in JavaScript’s parser tries to parse the dot notation on a number as a floating point literal.”
Should probably also mention the Function constructor in the eval section. Also object keys are always are type cast into strings so object[1] = "moo" becomes object["1"], this is rarely a problem but can be.
I'd add under setTimeout and setInterval that anything below 8ms may not work as expected across different browsers/hardware. Even setting 1ms to indicate "as soon as possible" may not occur as expected when repeatedly called.
also: the font size is a little small for my eyes in the code boxes - I can fix it of course with stylish but maybe that can be addressed directly on the site
We have a newer version of the website in the works, but it's getting delayed to my new job. I hardly have anytime at the moment to work with Yi Jiang on the style since I spend 5 hours a day sitting in a train. But that will change as soon as I manage to move.
I've seen so many people insist that Javascript code should be Semicolon free recently. It always felt wrong to me, mainly because I code in several languages and getting into the habit of not using semicolons felt dangerous. It's nice to know there's a genuine reason to continue using them.
This site is too light on details for me to trust its conclusions.
Under “The evil eval”, it concludes that you should never use eval simply because it sometimes executes in global scope. That does not seem like an obvious conclusion to me. Yes, it’s a mistake to use it on user input, but that is easily avoided. I think the site should give an example of a situation where you think you need eval, the problems eval necessarily brings in that case, and how to write that without eval. Otherwise, I don’t trust that the site writer has actually explored why people use eval or what eval might be able to provide that nothing else can.
Also, under “Automatic semicolon insertion”, the site does not mention the alternative to using semicolons everywhere, which is not using semicolons but remembering to put a semicolon before each line starting with parentheses. That is a valid alternate practice, and the site ignores the possibility without even discussing its problems.
The fact that each of those two sections contain grammar mistakes (comma splices) also signals a lack of attention to detail.
[+] [-] tkiley|15 years ago|reply
One quibble: In the "common pitfalls" section regarding the "this" object, they say that locally-defined functions within other functions never have any practical use. I might disagree: with a little coaxing, you can convince locally variables inside the constructor (both functions and other variables) to serve as private properties of an object; this is the only technique I know that allows for private properties.
(I haven't actually done this in code that has been maintained/used anywhere, I just did it as an experiment and filed it away as a "that's cool" for future reference)
Edit: Here is an example of what I'm talking about: https://gist.github.com/866103
[+] [-] eru|15 years ago|reply
Might also come in handy if you are into functional programming with Javascript.
[+] [-] benjisg|15 years ago|reply
Since all functions are objects in JS, you can create a function with some internal (private) functions and properties than return a object with some publicly accessible functions. A basic example:
https://gist.github.com/866343
Closure gives you a really powerful structure that lets you encapsulate your code and then you don't have to use this and risk clobbering the global window object :)
[+] [-] csomar|15 years ago|reply
1. If you use the "new" keyword, and don't execute the function. "x = new foo()". X becomes an "object". "foo()" is behaving like a class. You got to define the properties and methods of this class with the "this" keyword. Once you create your object with the "new" keyword, these variables got assigned to the object. And better, you can access them with the prototype.
2. If you execute the function in your code, that is you put "foo()": Open your FireFox with FireBug and notice two new global variables in the Windows object "get_my_private" and "set_my_private".
So it depends on the usage. "this" insides of a function is useful, if your intent is to use the function as a class. If not, it's dangerous, as the variables becomes global and may interfere with other variables.
[+] [-] csomar|15 years ago|reply
[+] [-] halostatue|15 years ago|reply
[+] [-] grigy|15 years ago|reply
http://ejohn.org/apps/learn/
[+] [-] mrspeaker|15 years ago|reply
[+] [-] Tomek_|15 years ago|reply
[+] [-] gregory80|15 years ago|reply
[+] [-] andreyf|15 years ago|reply
1. http://bonsaiden.github.com/JavaScript-Garden/#prototype
[+] [-] nfriedly|15 years ago|reply
So when you create a new instance of Bar, it's constructor still appears to be Foo even though it really isn't. Setting the prototype.constructor fixes that.
[+] [-] senorpedro|15 years ago|reply
[+] [-] extension|15 years ago|reply
A bit controversial, don't you think?
[+] [-] netghost|15 years ago|reply
If it's in a shared library, it is probably nicer to avoid. For instance, if you override a function on a native prototype, you might be overwriting some future function that browsers will implement. I've seen this done with Array.map for instance.
[+] [-] Kilimanjaro|15 years ago|reply
[+] [-] zoul|15 years ago|reply
[+] [-] atuladhar|15 years ago|reply
[+] [-] btipling|15 years ago|reply
[+] [-] ck2|15 years ago|reply
I'd add under setTimeout and setInterval that anything below 8ms may not work as expected across different browsers/hardware. Even setting 1ms to indicate "as soon as possible" may not occur as expected when repeatedly called.
also: the font size is a little small for my eyes in the code boxes - I can fix it of course with stylish but maybe that can be addressed directly on the site
[+] [-] BonsaiDen|15 years ago|reply
[+] [-] tomelders|15 years ago|reply
[+] [-] roryokane|15 years ago|reply
Under “The evil eval”, it concludes that you should never use eval simply because it sometimes executes in global scope. That does not seem like an obvious conclusion to me. Yes, it’s a mistake to use it on user input, but that is easily avoided. I think the site should give an example of a situation where you think you need eval, the problems eval necessarily brings in that case, and how to write that without eval. Otherwise, I don’t trust that the site writer has actually explored why people use eval or what eval might be able to provide that nothing else can.
Also, under “Automatic semicolon insertion”, the site does not mention the alternative to using semicolons everywhere, which is not using semicolons but remembering to put a semicolon before each line starting with parentheses. That is a valid alternate practice, and the site ignores the possibility without even discussing its problems.
The fact that each of those two sections contain grammar mistakes (comma splices) also signals a lack of attention to detail.
[+] [-] roryokane|15 years ago|reply
[+] [-] alexyim|15 years ago|reply
[+] [-] amadeus|15 years ago|reply
https://github.com/amadeus/dbg
[+] [-] koraybalci|15 years ago|reply
[+] [-] pistoriusp|15 years ago|reply
When the document scrolls it compares the scroll position to the stored offset positions.
If an article is close enough to the scroll offset it's highlighted.
[+] [-] hanifvirani|15 years ago|reply
[+] [-] sawyer|15 years ago|reply
[+] [-] Ruudjah|15 years ago|reply
[+] [-] kifou1|15 years ago|reply
[+] [-] simpsond|15 years ago|reply
[+] [-] wkasel|15 years ago|reply
[+] [-] kaffiene|15 years ago|reply
[deleted]