bonsaiden / javascript-garden Goto Github PK
View Code? Open in Web Editor NEWA collection of documentation about the most quirky parts of the JavaScript language.
Home Page: http://bonsaiden.github.com/JavaScript-Garden
License: MIT License
A collection of documentation about the most quirky parts of the JavaScript language.
Home Page: http://bonsaiden.github.com/JavaScript-Garden
License: MIT License
It might be cool to have some sort of "presentation" mode so people can spread the word easily. I know the amount of text might be problematic.
Perhaps this needs to be a separate "mini garden" or something. Just a thought. :)
It might be helpful to link to the actual spec snippets for additional info on various topics discussed in the document.
This is the current example for when semicolon insertion bites back:
return
{
foo: 1
}
The rest of the section then proceeds to explain how such issues are avoided by just using semicolons everywhere.
This is bullshit. Read the example again. Does just putting semicolons in that code fix the problem? No, but removing the newline after return
does. You're just propagating FUD that I wrote a whole blog article about.
The second example you used is a little better, but it's convoluted and overly complicated while explained. There is a much simpler example and shorter explanation in this document on mozilla.org.
My point: you can advise people to always use semicolons, but please pay attention on the kind of examples you provide. Just don't tell people that semicolons should never be omitted
because that simply isn't true. Here is a fork of jQuery with most semicolons removed—all tests pass in all browsers. See if, with all your JavaScript expertise, you can find a bug in it.
Hi,
All the examples on the web show contrived examples on closures, but always mention its use. Could you show one of two real world examples of usage patterns?
KR,
Tom
You have:
Bar.prototype = Foo.prototype;
which should be:
Bar.prototype = new Foo();
Bar.prototype.constructor = Bar;
See http://wiki.pageforest.com/#jsgardenbug for problems caused by your example.
In the document you recommend using a for
loop but a while
loop is also commonly used.
The arguments object creates getter and setter functions for both its properties as well as the functions formal parameters.
The arguments object creates getter and setter functions for both its properties as well as the function's formal parameters.
Line 39, Column 15: Stray end tag section.
"In order to retrieve the value of [[Class]] one can has to make use of the toString method of Object.prototype." -- should probably be fixed (or kept just for fun!)
You can use this table http://goo.gl/tD1jr
In the document you show an example using the Array
constructor to specific the length
of the array.
new Array(3); // Result: [undefined, undefined, undefined]
In reality it creates a sparse array with no indexes. For example in environments that support ES5
(new Array(3)).forEach(function(v, i) { alert(i) }); // alert nothing.
Could you please try to come up with some other kind of navigation specifically for iPad? I'm aware you might not have access to the device yet... Still it would be great to have this fixed.
I think the issue stems from the fact that mobile Safari doesn't support fixed positioning. You may find some workarounds for the issue here. Apparently a bit of JS ought to do the trick.
I would really love to read the site on iPad. :)
Greetings,
Under the section Deleting properties I noticed some minor language issues...
That section currently reads:
The only way to actually remove a property from an object is to use the delete operator; setting the property to undefined or null does only remove the value associated with the property, but not the key.
The above outputs both bar undefined and foo null - only baz got actually removed and is therefore missing from the output.
The following are the corrected paragraphs with the changes in strong:
The only way to actually remove a property from an object is to use the delete operator; setting the property to undefined or null only removes the value associated with the property, but not the key.
The above outputs both bar undefined and foo null - only baz was removed and is therefore missing from the output.
In objects decsription, should be 'except', not 'expect' :)
On chrome 10, !!'0' resolves to true, not false as stated in the Type Casting section.
Open question: Is this is cross-browser issue or is !!'0' true on all browsers?
http://bonsaiden.github.com/JavaScript-Garden/
says something like....
�‹��Žëv�Ç•.ø¿ž" ¯1@��‘”OÛ"‰5�EÙì#Q�“nO�š«§PH)�ªÐu!�ëèiæQ΋�ïûöÞ�‘—_�é³Öpi @ufddľû�O�óõ÷/Þþû�/««Õõôtô”?ªéxvùl¯ží�Ž_ü{zU�ÏíWýy]¯ÆÕäj¼XÖ«g{ëÕÅÑ�ýJ}ý›££�›‹êÕËw§O�óc=;o.Þ���÷¯šÕ´>ý×ñ‡ñ›É¢¹YU��/ÎëÙÓ�ûBÏä¿ô‹=q6¾®Ÿí�×KÝÔÌg{Õd>[Õ3LâÏëæ¼®Vó*�º¿¬þ¯u³x¿¬Æ³óê›éøvYÎrÚÌÞW‹zúlo¹º›ÖË«º^íUW‹úâÙÞd¹<¹ÔœŽñë^u]Ÿ7ãg{ãéôcF¸Y4³Uk}�‹zb«j+|6?¿+Vè¼ù�ÿÒ¢ÎÆ�OôéÕáeħiél%qéš»;mNŸŽý%�‹¹,æ{§¯øãéÉøôé ¾î\3?û©ž¬°pßÛ/›®»YÌWóÕÝM½wúöª®ÒŸ›®¿�/ç·3\vS/Vw{§O'óóú�Ÿ�;ûÁ?}z¢�7 q±žMH�˜Ü7ñë¦kWW .ûËü¶²�ño�¾º�ƒF6Ý8™Î—ëE�›_øo¢&PI½¨g“zã�ãÅåú�¤‰;¹ öØôa<Û–wÓ×�,��x£Ÿz0yy3Þò
°ÄrµXOVó�g]üµé1õ�ÇÓ†»ðÒ�Ó£&óë›ñ¢Yb„MwŽ�‹ñ�žò?·^Åù”K¡[b�Š9o�äb�Þ™Îç7å ø°j 7D'�¿Ýt;IsQÞkŸ¤��Ž1ÅM÷7XÔ1ö»=Fþt×q&ã媙]b"˜På�mzèzv^_4³ú<ø#}��ã>�iÍÖÓé=S��C‘�ë�ÍÔïã‡÷Ü·j®ëùš”l�‚Ô�k�õ§�ï OêÅý£.ëëf2ŸBŠŸ>_¯æ×ãU3©Ò‡ØÖ%$�Ø»Xœ�È°§'K�$|Þ‘�'��-±'µU/�dá�#O ‚žÆXq)�jÕœ?Ûk‹FÈÓ§’Ö�ìé nƒÄœ]�‰^ÿ¦jÀ®Õåb~‹Í�'M§6éj~Q�Ï'’xáù¬�Ÿai«�6åz¾\U£ÿ¢Êº«Ày«%¯æ7…¦„ļ\Œ¯¯9,µôz|Y�W¯VÕeó�"âüC3‘���?Ì�1ñ5žrÝ............
Safari 2 will throw a syntax error if you remove the semi colon after a throw statement. http://dean.edwards.name/weblog/2007/04/packer3/
In the section 'performance myths and truths' in the section 'The arguments Object', we find:
The arguments is, except for the two cases named at the start of this section, always created.
I don't see any cases named at the start of the section for "the two cases..." to refer to. Perhaps the cases were removed and this sentence is a dangling reference?
Also, I think it would read better if it started "The arguments object is..." but that's perhaps a matter of taste.
The document contains:
Unless checking whether a variable is defined, typeof should be avoided at all costs." and later
and
Just like the typeof operator, every other use of it should be avoided.
That's a bit unfair and alarmist. typeof
has it's place and can be used to check types of say a literal vs an object instance of basic types of number
or string
when you aren't concerned with object instances.
Also you should note that instanceof
may cause a memory leak in IE when used against host objects (there is an old ajaxian post on it).
Things that need to be done before any translation can be started.
Everyone who is interested in a translation, please leave a comment on this issue.
Consider splitting up the navigation in categories (tree like). This will make it faster to find specific topics. Now it's bit of a mish mash (no clear structure).
versions of IE, Safari have problems with for-in
loops. Some versions of IE won't iterate over shadowed properties, versions of Safari may iterate multiple times over shadowed properties.
It reads
Also, watching the length of the prototype chains and breaking them up if necessary can avoid possible performance issues.
Should probably read
Also, watch the length of the prototype chains and break them up if necessary to avoid possible performance issues.
Perhaps throw in some real-life examples of the bigger code blocks on JsFiddle?
Best,
Oskar
in Objects section, http://bonsaiden.github.com/JavaScript-Garden/#objects
example 3,
2. toString(); // note the space
raises SyntaxError. according to the spec section 7.8.3 http://es5.github.com/#x7.8.3 , space is set to the left of dot.
2 .toString(); // note the space
thanks for your great document.
All of the constructor examples under its section are like new Foo()
when new Foo
would do. Maybe through one in the mix.
Also you can avoid new
with something like:
function Foo(a, b, c) {
return new foo.prototype.constructor(a, b, c);
}
Foo.prototype.constructor = function(a, b, c) {
this.a = a;
this.b = b;
this.c = c;
};
Foo.prototype.constructor.prototype = Foo.prototype;
OR
function Foo(a, b, c) {
var instance = new Dummy;
instance.a = a;
instance.b = b;
instance.c = c;
return instance;
}
function Dummy() { }
Dummy.prototype = Foo.prototype;
The last paragraph of the Functions section reads:
Since assignments only happens at runtime, the value of Foo will default to undefined before the corresponding code is executed.
However, there is no "Foo" with a capital "F" mentioned in that section. I think you meant "foo". Or there's something going on that I don't understand.
Are you guys not supporting Internet Explorer? I get a javascript error in IE8 when viewing the page:
garden.js, line 34 character 13
'this.names[...].id' is null or not an object
This happens on page load, and every time you try to scroll. It also fails to render the right hand navigation (I assume this is because the javascript error).
So I don't see the perf concern of [].slice.call(arguments)
, use it if u need to slice up the arguments
object:
var args = slice.call(arguments),
var first = slice.shift(); // remove first
foo(first);
bar.apply(null, args);
So basically use it when you need it and not when you don't :D
delete
operator has a very complicated behaviour: http://perfectionkills.com/understanding-delete/ - it would be nice to see a short description of its' mechanism
{}.hasOwnProperty(...)
in hasOwnProperty article throws an error. Seems the right way to do is:
({}).hasOwnProperty(...)
.
I think it's worth mentioning that assigning objects or arrays to variables does not create a new copy of said object but merely references it (with exception of using the new keyword). Same goes for variables assigned to other variables of those types...only references are copied over. So changing one variable will also change the other. Maybe also mention how Javascript passes arguments i.e. whether it's by reference or value.
In doc/semicolon.md
the following lines should be corrected
// missing slashes '//'
return; <- inserted, breaks the return statement
// missing a space in the beginning of the comment
window.someLibrary = {}; //<- inserted
For some reason you avoid this explanation, but I think, it’s a vital thing for understanding JS. Every time you use dot operator (or square brackets) JS trying to convert the thing on the left of operator to object.
"string".length
doesn’t make any sense, because string is not an object and can’t have properties, but JS actually does Object("string").length
. The same way as "6" / 2
doesn’t make sense, but JS “replaces” it with Number(6) / 2
.
Good example on understanding this difference:
var a = 5;
a.prop = "blah";
alert(a.prop); // undefined
That means that “Everything in JavaScript acts like an object…” is not correct. a
doesn’t act like object here.
The arguments object is always created with the only two exceptions being the cases where it > is declared as a name inside of a function or one of its formal parameters. It does not matter
whether it is used or not.
This is incorrect at least for V8. Arguments object is not created if it is not used and even if it is used in some cases V8 can avoid creating arguments object.
In the above code, foo can no longer be a subject to inlining since it needs to know about both itself and its caller.
This logic is also incorrect. Inlining can take care of the fact that foo accesses it's caller.
Speaking of V8:
Accessing arguments.callee currently in function makes function non-optimizable.
But accessing it does not disable inling of functions above it. Consider the following example:
function baz() {
if (arguments.callee.caller != foo || arguments.callee.caller.caller != bar)
throw new Error("something fishy is going on");
}
function foo() { return baz(); }
function bar() { return foo(); }
for (var i = 0; i < 1000000; i++) bar();
Here V8's optimizing backend will be able to inline foo into bar despite the fact that baz accesses the fact that foo is called from bar.
In the prototypes section, you write:
In the above, the object
test
will inherit from bothBar.prototype
andFoo.prototype
; hence, it will have access to the functionmethod
that was defined on Foo. But it will not have access to the propertyvalue
of aFoo
instance, since that property gets defined in the constructor ofFoo
. But this constructor has to be called explicitly.
It's not clear to me what is meant here. It's possible to access test.value
, so what do I not have access to?
Excellent documentation, thanks for the work you have put in. The formatting is nice. Just mentioning the naming of the inheritance type according to JavaScript The Good Parts.
In the document you assert that setTimeout
, and setInterval
are using eval()
, though draft spec exists for setTimeout
and setInterval
I am wary of assuming all implementations would conform to it. As for example at least IE6-8 will detect the presence of an arguments
object which suggest it's using the Function
constructor and not eval()
:
setTimeout('alert(typeof arguments)', 50);
Also inline event handlers can execute code.
<button onclick="window.foo=2">click me</button>
Just noticed that this is hosted on github, after sending an email, dooh.
Here is the copy:
The arguments Object
"The arguments is, except for the two cases named at the start of this
section, always created."
Not really true, if it's not used in any function having access to
this scope it's not created in the most cases and engines.
"Array.prototype.slice.call"
Please don't show this code, somebody will copy it, make some benchmarks.
Array.apply(null, arguments); should be at least twice as fast
usually, but still this should avoided as often as possible.
The class of an object
Just wanted to note that a ES5 errata changed
Object.prototype.toString, so toString.call(null) returns [object
Null] and undefined [object Undefined]
In general, there is no need use the strict equality operator with
typeof, but that's more an personal preference.
undefined and null
"But this variable is not a constant, meaning that it can be easily
overwritten which then leads to abstruse bugs"
undefined is not writable in ES 5, but still not an keyword (so it
could be shadowed)
"The value undefined is returned in the following cases:"
The list is not conclusive (eg void 0, [].shift()), i would change to
"some example to get the undefined value"
In your list of ways to get undefined you don't mention local variables that have been declared but not assigned.
var undefined = 10;
(function () {
var undefined;
console.log(undefined)
})()
> undefined
I find it also more secure than an additional parameter in the wrapper function. The function parameters are at the top of the file and the call at the bottom. If you call it with a new parameter and forget to update the definition, it may still work but gives silly errors because you changed undefined.
Consider animating transitions between sections (ie. if you click "Type casting" at the navigation, it could move there smoothly instead of instantly). I've been probably using iPad too much... Still this might be a nice visual touch.
var foo = [1, 2, 3, 4, 5, 6];
foo.hasOwnProperty(5); // true - 6 exists
foo.length = 3;
foo; // [1, 2, 3]
foo.hasOwnProperty(5); // false - we have reduced array
foo.length = 6;
foo; // [1, 2, 3]
foo.hasOwnProperty(5); // false
foo.join(); // "1,2,3,,," join lies, because it uses length property
foo[5] = void 0; // set undefined
foo.hasOwnProperty(5); // true, because we have created undefined var manually
foo.join(); // "1,2,3,,," same
Mistake :) Don't know how to delete issue...
I noticed in the document you used words like magic
and evil
when referring to aspects of the language that are clearly explained in the specification (not magic) and have practical uses (not necessarily evil). I would dig it if you removed the flowery language.
Hello!
Wouldn't it be safer to use
({}).hasOwnProperty.call(o, ['foo'])
instead of
o.hasOwnProperty('foo')
?
Consider this:
var o = {foo: 5, hasOwnProperty: function() { return false; } };
This might especially be important if you're allowing the user to just store about anything in an object. Or are there any keys that definitely "break" a JavaScript object, even if using tricks like the one above?
When discussing the prototype-based programming paradigm, I see it referred to as "prototypal" more than "prototypical". Outside of programming the two words are synonyms, but in this context it helps disambiguate. A phrase like "JS has prototypical inheritance" could mean "JS inheritance is prototype-based" or "JS inheritance works like original inheritance systems". Using the less common "prototypal" helps clarify that you mean the former.
Great site, though. Thanks!
In the section 'Modification "magic"' in the section 'The arguments Object', there's a paragraph that reads:
As a result, changing the value of a formal parameter will also change the value corresponding formal parameter, and the other way around.
I think perhaps this was meant:
As a result, changing the value of a formal parameter will also change the value of the corresponding member of the arguments object, and the other way around.
Or something like that.
In the document you generalize on the Number
and String
constructors, but remember Array(5)
will work just like new Array(5)
, Function('return 3')
will work just like new Function('return 2')
, and RegExp('\\d')
will work just like new RegExp('\\d')
.
The "Best practices" section's English could do with an improvement:
$ git diff remotes/origin/master master
diff --git a/doc/timeouts.md b/doc/timeouts.md
index 0660b04..ba0693e 100644
--- a/doc/timeouts.md
+++ b/doc/timeouts.md
@@ -116,11 +116,12 @@ function.
### Best Practices
-**Never** use a string as the parameter of `setTimeout` or `setInterval` its a
-sign of **really** bad code, if you need to supply arguments to the function,
-pass an anonymous function which then calls your function. Also avoid
-`setInterval` since its hard to control and when you loose the returned ID,
-there's no easy way to clear it.
+**Never** use a string as the parameter of `setTimeout` or `setInterval`. It is
+a sign of **really** bad code. If you need to supply arguments to the function,
+pass an anonymous function which then calls your function.
+
+Also, avoid `setInterval`. It is hard to control and, when you lose the
+returned ID, there's no easy way to clear it.
[1]: http://en.wikipedia.org/wiki/Document_Object_Model
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.