Skip to content

Commit ee8f975

Browse files
committed
Conflicts: template/template.html
2 parents a688d55 + b9688d2 commit ee8f975

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+1569
-2493
lines changed

.gitignore

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
1-
/index.html
2-
/garden.css
3-
*.tmp
1+
/html/index.html
2+

README.md

Lines changed: 34 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,44 @@
1-
JavaScript Garden - A Guide for JavaScript Core
2-
===============================================
1+
JavaScript Garden
2+
=================
33

44
**JavaScript Garden** is a growing collection of documentation about the most
5-
quirky parts of the JavaScript. It gives advice to avoid common coding
6-
mistakes, subtle bugs, as well as performance issues non expert JavaScript
7-
programmers may encounter on their endeavours into the depths of the language.
5+
quirky parts of the JavaScript programming language. It gives advice to
6+
avoid common mistakes, subtle bugs, as well as performance issues and bad
7+
practices that non-expert JavaScript programmers may encounter on their
8+
endeavours into the depths of the language.
89

910
JavaScript Garden does **not** insist on teaching JavaScript. Former knowledge
10-
of the language is recommended in order to understand the topics covered in this
11-
guide.
11+
of the language is strongly recommended in order to understand the topics covered
12+
in this guide. In order to learn the basics of the language, please head over to
13+
the excellent [guide][1] on the Mozilla Developer Network.
1214

13-
TODO
14-
----
15+
### The authors
1516

16-
Besides a lot of copy-editing and rewording / styling for consistency, the
17-
following topics are currently missing from the guide:
17+
This guide is the work of two lovely Stack Overflow users, [Ivo Wetzel][6]
18+
(Writing) and [Zhang Yi Jiang][5] (Design).
1819

19-
- The evil `eval`
20-
- The Global Object
21-
- Casting of Values
22-
- Converting of Numbers
20+
If case you are interested in additional guidance or reviews concerning your JavaScript
21+
projects, Ivo Wetzel offers these on a freelance basis. Please feel free to
22+
contact him via [e-mail][7] for further details.
2323

24-
License
25-
-------
24+
### Contributors
2625

27-
JavaScript Garden is published under the MIT license and hosted on
28-
[GitHub](https://github.com/BonsaiDen/JavaScript-Garden). If you find errors or
29-
typos please file an issue or a pull request on the repository.
26+
- [Caio Romão][8] (Spelling corrections)
27+
- [Andreas Blixt][9] (Language corrections)
28+
29+
### License
30+
31+
JavaScript Garden is published under the [MIT license][2] and hosted on
32+
[GitHub][4]. If you find errors or typos please [file an issue][3] or a pull
33+
request on the repository.
34+
35+
[1]: https://developer.mozilla.org/en/JavaScript/Guide
36+
[2]: https://github.com/BonsaiDen/JavaScript-Garden/blob/next/LICENSE
37+
[3]: https://github.com/BonsaiDen/JavaScript-Garden/issues
38+
[4]: https://github.com/BonsaiDen/JavaScript-Garden
39+
[5]: http://stackoverflow.com/users/313758/yi-jiang
40+
[6]: http://stackoverflow.com/users/170224/ivo-wetzel
41+
[7]: mailto:[email protected]
42+
[8]: https://github.com/caio
43+
[9]: https://github.com/blixt
3044

doc/arguments.md

Lines changed: 79 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,86 @@
1-
### Function Arguments
1+
## The `arguments` object
22

3-
Inside a JavaScript function you have access to a special variable called
4-
`arguments`, which is a list of the parameters the function was called with. This
5-
is useful when writing functions that deal with variable number of arguments.
3+
Every function scope in JavaScript can access the special variable `arguments`.
4+
This variable holds a list of all the arguments that were passed to the function.
65

7-
It's important to know that `arguments` is **not** an `Array`, it has some of
8-
the semantics of an array - namely the `length` property - but it does not
9-
inherit from `Array.prototype`, it is an `Object`.
6+
> **Note:** In case `arguments` has already been defined inside the functions
7+
> scope either via a `var` statement or being the name of a formal parameter,
8+
> the `arguments` object will not be created.
9+
10+
The `arguments` variable is **not** an `Array`. While it has some of the
11+
semantics of an array - namely the `length` property - it does not inherit from
12+
`Array.prototype` and is in fact an `Object`.
13+
14+
Due to this, it is not possible to use standard array methods like `push`,
15+
`pop` or `slice` on `arguments`. While iteration with a plain `for` loop works
16+
just fine, it is necessary to convert it to a real `Array` in order to use the
17+
array like methods on it.
18+
19+
### Converting to an array
20+
21+
The code below will return a new `Array` containing all the elements of the
22+
`arguments` object.
1023

11-
Due to this fact, one cannot use the standard array methods like `push`, `pop`,
12-
`slice` etc. with it. While iteration with a plain `for` loop works just fine,
13-
one has convert it to a real `Array` in order to use the named methods.
14-
1524
Array.prototype.slice.call(arguments);
1625

17-
This will return a new `Array` containing all the elements from the `arguments`
18-
object, note that this is **slow**, try to avoid at all costs in performance
19-
critical code.
26+
This conversion is **slow**, it is not recommended to use it in performance
27+
critical sections of code.
28+
29+
### Modification "magic"
30+
31+
The `arguments` object creates getter and setter functions for both its properties
32+
as well as the functions formal parameters.
33+
34+
As a result, changing the value of a formal parameter will also change the value
35+
corresponding formal parameter, and the other way around.
36+
37+
function foo(a, b, c) {
38+
arguments[0] = 2;
39+
a; // 2
40+
41+
b = 4;
42+
arguments[1]; // 4
43+
44+
var d = c;
45+
d = 9;
46+
c; // 3
47+
}
48+
foo(1, 2, 3);
49+
50+
> **ES5 Note:** These getters and setters are not created in strict mode.
51+
52+
### Performance myths and truths
53+
54+
The `arguments` is, except for the two cases named at the start of this section,
55+
always created. It doesn't matter whether it is used or not. Both getters and
56+
setters are **always** created; thus, using it has nearly no performance impact
57+
at all, especially not in real world code where there is more than an access to
58+
the arguments object properties.
59+
60+
However, there is one case which will drastically reduce the performance in
61+
modern JavaScript engines. That case is the use of `arguments.callee`.
62+
63+
function foo() {
64+
arguments.callee; // do something with this function object
65+
arguments.callee.caller; // and the calling function object
66+
}
67+
68+
function bigLoop() {
69+
for(var i = 0; i < 100000; i++) {
70+
foo(); // Would normally be inlined...
71+
}
72+
}
73+
74+
In the above code, `foo` can no longer be a subject to [inlining][1] since it
75+
needs to know about both itself and its caller. This not only defeats possible
76+
performance gains due to inlining, it also breaks encapsulation since the
77+
function may now be dependent on being called in a specific context.
78+
79+
It is highly recommended to **never** make use of `arguments.callee` or any of
80+
its properties.
81+
82+
> **ES5 Note:** In strict mode, `arguments.callee` will throw a `TypeError` since
83+
> its use has been deprecated.
2084
21-
> **Note:** Don't use `arguments` as a parameter name for functions, since it will
22-
> [override](#scopes) the default `arguments` object.
85+
[1]: http://en.wikipedia.org/wiki/Inlining
2386

doc/arrayctor.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
## The `Array` constructor
2+
3+
Since the `Array` constructor is ambiguous in how it deals with its parameters,
4+
it is recommended to always use the `[]` notation when creating new arrays.
5+
6+
[1, 2, 3]; // Result: [1, 2, 3]
7+
new Array(1, 2, 3); // Result: [1, 2, 3]
8+
9+
[3]; // Result: [3]
10+
new Array(3); // Result: [undefined, undefined, undefined]
11+
new Array('3') // Result: ['3']
12+
13+
In cases when there is only one argument being passed to the `Array` constructor,
14+
and that argument is a `Number`, the constructor will use that number as the
15+
*length* of the new array to be created.
16+
17+
This behavior only comes in handy in a few cases, like repeating a string, in
18+
which it avoids the use of a `for` loop.
19+
20+
new Array(count + 1).join(stringToRepeat);
21+
22+
### In conclusion
23+
24+
The use of the `Array` constructor should be avoided as much as possible. The `[]`
25+
notation is definitely preferred. It is shorter and has a clearer syntax; thus,
26+
it also increases the readability of code.
27+

doc/arrays.ctor.md

Lines changed: 0 additions & 26 deletions
This file was deleted.

doc/arrays.md

Lines changed: 38 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,60 @@
1-
### Arrays
1+
## Arrays
22

3-
Although the `Array` in JavaScript is an `Object`, there's no good reason to use
4-
the [for in loop](#forinloop) in order to iterate over it. In fact there
5-
a number of very good reasons **against** the use of `for in` on an `Array`.
3+
Although arrays in JavaScript are objects, there are no good reasons to use
4+
the [for in loop](#forinloop) in for iteration on them. In fact there are a
5+
number of good reasons **against** the use of `for in` on arrays.
66

7-
> **Note:** There are **no** so called *associative arrays* in JavaScript.
8-
> JavaScript only has [objects](#objects) for mapping keys to values. And while
9-
> *associative arrays* **preverse** order, objects do **not**.
7+
> **Note:** JavaScript arrays are **not** *associative arrays*. JavaScript only
8+
> has [objects](#objects) for mapping keys to values. And while associative
9+
> arrays **preserve** order, objects do **not**.
1010
11-
While it may seem like a good choice at first, to trade the some speed against
12-
the readability of the `for in` construct, this has **major** implications on
13-
performance.
11+
Since the `for in` loop enumerates all properties on the prototype chain and
12+
the only way to exclude those properties is to use
13+
[`hasOwnProperty`](#hasownproperty), it is already up to **twenty times** slower
14+
than a normal `for` loop.
1415

15-
The `for in` does in fact iterate over the indexes of an `Array`. But it does
16-
also traverse the prototype chain. So one already has to use `hasOwnProperty` in
17-
order to make sure to filter out unwanted properties, and still if any
18-
additional properties happen to be defined on the array, they will still make it
19-
through this filter.
16+
### Iteration
2017

21-
Combining the already slow nature of the prototype traversing `for in` with the
22-
use of `hasOwnProperty` results in a performance degradation of a factor of up
23-
to **20x**.
24-
25-
So if you want to iterate over an `Array` in JavaScript, **always** use the
26-
classic `for` loop construct.
18+
In order to achieve the best performance when iterating over arrays, it is best
19+
to use the classic `for` loop.
2720

2821
var list = [1, 2, 3, 4, 5, ...... 100000000];
2922
for(var i = 0, l = list.length; i < l; i++) {
3023
console.log(list[i]);
3124
}
3225

33-
As you can see, there's one extra catch in the above example. That is the
34-
caching of the length via `l = list.length`.
26+
There is one extra catch in the above example, which is the caching of the
27+
length of the array via `l = list.length`.
28+
29+
Although the `length` property is defined on the array itself, there is still an
30+
overhead for doing the lookup on each iteration of the loop. And while recent
31+
JavaScript engines **may** apply optimization in this case, there is no way of
32+
telling whether the code will run on one of these newer engines or not.
3533

36-
Although the `length` property is defined on the array itself, there's still an
37-
overhead for doing the lookup on each iteration. And while recent JavaScript
38-
engines **may** apply optimization in this case, one can never be sure that
39-
those optimizations are actually in place, nor can one be sure whether they
40-
reach the speed of the above caching. In fact leaving out the caching may result
41-
in a performance degradation of a factor of up to **2x** (and even more in older
42-
engines).
34+
In fact, leaving out the caching may result in the loop being only **half as
35+
fast** as with the cached length.
4336

44-
**The length Property**
37+
### The `length` property
4538

46-
The `length` property of an `Array` is not just a plain property. While its
47-
`getter` just returns the number of elements in the array, its `setter` on
48-
the other hand can be used to **truncate** the array.
39+
While the *getter* of the `length` property simply returns the number of
40+
elements that are contained in the array, the *setter* can be used to
41+
**truncate** the array.
4942

5043
var foo = [1, 2, 3, 4, 5, 6];
5144
foo.length = 3;
5245
foo; // [1, 2, 3]
46+
5347
foo.length = 6;
5448
foo; // [1, 2, 3]
5549

56-
As one can see, assigning a smaller length truncates the array, but increasing
57-
the length it has no effect at all.
50+
Assigning a smaller length does truncate the array, but increasing the length
51+
does not have any effect on the array.
52+
53+
### In conclusion
54+
55+
For the best performance it is recommended to always use the plain `for` loop
56+
and cache the `length` property. The use of `for in` on an array is a sign of
57+
badly written code that is prone to bugs and bad performance. Additionally,
58+
never should any assumptions be made whether the JavaScript engine will apply
59+
optimization to the code or not.
5860

59-
#### Best Practices
60-
Always use the `for` construct and cache the length to achieve the best
61-
performance, don't make any assumptions about the JavaScript engine optimizing
62-
**anything**.
63-

0 commit comments

Comments
 (0)