Is <!-- valid javascript? - javascript

I recently had to fix a bug that manifested sometimes in Internet Explorer. The bug was that, sometimes, the parser choked on code like
<script type="text/javascript">
<!-- // comments -->
/*...*/
</script>
Which we fixed by correcting the comment.
My question is: is "<!--" valid javascript code, or not? I tried testing it with firebug, and it only says" Undefined". JSFiddle didn't faze. IE only choked on it some of the times (reloading the page in question would show up the result of the script involved).
While knowing that, for historical reasons, an HTML comment inside js could be valid depending on its exact position and the phase of the moon is indeed useful, I was more interested in answers like "var <!-- foo is valid js code, but <!-- on its own is not. Here's why:..."
I did some analysis in firebug:
var x = 2;
var y = 3;
var z = 0;
console.log(x);
console.log(y);
y<!--x;
console.log(x);
console.log(y);
z = y<! --x;
console.log(x);
console.log(y);
console.log(z);
resulting in the following:
2
3
2
3
1
3
false
The difference between the first and second tries is interesting.
I then tried
z = (y <!--x);
console.log(z);
Which failed with
SyntaxError: missing ) in parenthetical

First to answer your question on Is <!-- valid JavaScript: No, it is not, in none of the forms you gave in your question. This is because it is not valid according to the JavaScript BNF grammar which you can find here: http://tomcopeland.blogs.com/EcmaScript.html
If you are interested, here's why you do see it inside script blocks: It is the HTML comment character. You do see it very often within script tags like this:
<script>
<!--
.. JavaScript code...
// -->
</script>
The reason is that old browsers (and with "old" I mean "stone age" like Netscape 1.0) that do not even support JavaScript and would otherwise just show the code on the screen. By doing it this way those older browsers treat the JavaScript as HTML comments and do not show it. Newer browsers ignore this and just run the JavaScript.
This is how it actually works (from http://www.w3.org/TR/html401/interact/scripts.html#h-18.3.2): The JavaScript engine allows the string <!-- to occur at the start of a SCRIPT element, and ignores further characters until the end of the line. JavaScript interprets // as starting a comment extending to the end of the current line. This is needed to hide the string --> from the JavaScript parser.
Because all browsers nowadays support JavaScript (even if it is turned off) you do not need to do this anymore. It is actually bad practice to do so because of these reasons (from http://www.javascripttoolbox.com/bestpractices/#comments):
Within XHTML documents, the source will actually be hidden from all browsers and rendered useless
-- is not allowed within HTML comments, so any decrement operations in script are invalid
An even deeper explanation and all the cons and pro's can be found here: http://lachy.id.au/log/2005/05/script-comments

In older browsers, it was required to have these comments inserted because the browsers couldn't parse the javascript properly. it would try to literally parse the javascript as html which caused script execution failures.
Today, browsers don't need this.

It's not.
If you go to the standard, you'll see that a < can only exist in a RelationalExpression, which <!-- is not as it hasn't got anything on the left-hand side.

Comments in Javascript are like other C-type languages (// for single line, /* */ for blocks.

Related

What does --> do in JavaScript?

I have been unable to find any reference to this statement in any book, manual, or site. As far as I can tell, it functions exactly as a // comment. For example:
console.log("1");
--> console.log("2");
console.log("3");
will print
1
3
What I'm curious about is exactly what the difference between --> and // is, if any exists, and also why --> seems to completely absent from all the JavaScript references I've seen - the only reason I found out about it at all was because I accidentally typed it into Adobe Dreamweaver, and it was highlighted as a comment. Thanks!
Edit: Here is a functional jsFiddle demonstrating the behavior.
Edit 2: I've tested further, and I've discovered a few things.
This only works if there are exactly two dashes. -> and ---> will throw errors.
This only works with a "greater than" symbol. --< will throw an error.
This will not work in the middle of or at the end of a line. console.log("1"); --> console.log("2"); will throw an error.
My guess is that the JavaScript engine, forgiving as always, is silently ignoring the line because it looks like the end of an HTML comment (<!-- -->). JavaScript inlined in HTML has historically been wrapped in an HTML comment so that browsers that don't support JavaScript would not try to parse it.
Edit:
I've done some research, and this is indeed the case.
From V8's scanner.cc:
If there is an HTML comment end '-->' at the beginning of a
line (with only whitespace in front of it), we treat the rest
of the line as a comment. This is in line with the way
SpiderMonkey handles it.
From Rhino's Comment.java:
JavaScript effectively has five comment types:
// line comments
/* block comments */
/** jsdoc comments */
<!-- html-open line comments
^\s*--> html-close line comments
The first three should be familiar to Java programmers. JsDoc comments
are really just block comments with some conventions about the formatting
within the comment delimiters. Line and block comments are described in the
Ecma-262 specification.
Note that the --> comment is not part of the Ecma-262 specification.
This is not a comment. If you see it as a comment inside of code, then its probably showing as some kind of hanging chad HTML comment instead of the normal "//".
What's happening in this case is you are comparing using the greater than and then subtracting 1. Here are some examples...
var x = 3; var y = 3; console.log(x --> y);
false and x is now 2
If you place the normal comment characters "//", you'll get a syntax error (which you should)
The reason this is working as a comment is because it is returning as undefined. This is not safe to use as a comment. Oddly enough, it works fine in Chrome and you can throw all kinds of characters at it if you start the line with "-->".
--> something for nothing ~!####%$#%^$&%^&*()_+_=-=[]\];'\||?>;';;; alert('test'),,143187132458
However, within IE 11, it is always a syntax error. Very cool find

Why is the HTML comment open block valid JavaScript?

In some old code, I found a JavaScript file with it's contents surrounded by HTML comments.
I understand the reasons for doing that in old browsers, but not how it is valid JavaScript in any way.
The expression <!-- is undefined in Chrome and IE's console.
Is this a special case handled by the interpreter (http://javascript.about.com/library/blhtmcmt.htm) still defined in the ECMAScript standards and working in modern browsers, or does the combination of these symbols happen to result in something that's undefined?
I read this as something like "less-than NOT decrement", which seems nonsensical with no operands. Any of these by themselves return a syntax error.
I get why things like "use strict"; are valid, but do nothing, but I can't tell what this code actually does.
I'm probably overthinking it, but would like to understand what's going on
This is a non-standard feature that browsers and JavaScript engines have always implemented. Nowadays, it cannot be removed from the Web platform, as that would break backwards compatibility. It’s detailed in the JavaScript / Web ECMAScript spec:
<!-- must be treated as the start of a SingleLineComment —
equivalent to //.
var x = true;
<!-- x = false; // note: no syntax error
x; // true
--> at the start of a line, optionally preceded by whitespace or
MultiLineComments, must be treated as a SingleLineComment —
equivalent to //.
var x = true;
--> x = false; // note: no syntax error
x; // true
var x = 1;
/*
multiline comment!
x = 2;
*/ --> x = 3;
x; // 1
<!-- begins a single-line Javascript comment, believe it or not.
This is used to allow <script> blocks to hide themselves from browsers that don't recognize the <script> tag (eg, Netscape 2), by wrapping all of the script contents in an HTML comment.
This should no longer be used.

Razor/JavaScript and trailing semicolon

Using Visual Studio 2012, on a Razor view page, in the JavaScript section, I am getting what I think is a battle between Razor syntax vs JavaScript syntax. In particular, the trailing semicolon in the script section is flagged by intellisense and a compiler warning (not error) is delivered:
'Warning 13 Syntax error'.
If I remove it, then I get a statement termination recommendation (ReSharper in this case, but just good practice).
<script type="text/javascript">
$().ready(function(){
var customer = #Html.Raw(ViewBag.CustomerJSON); // <- Razor (I think) doesn't like this semicolon
});
</script>
Is this a bug in Razor? If so, is there a way I can rewrite this to avoid this issue?
Is this a bug in Razor?
Absolutely not. Run your application, and it will work as expected.
It is a bug in the tools you are using (Visual Studio 2012, ReSharper, ...) that are incapable of recognizing perfectly valid syntax and warning you about something that you shouldn't be warned about. You could try opening an issue on the Microsoft Connect site and signalling this bug if that hasn't already been done.
Since this still seems to be happening and it is a nuisance I figured I will at least let others know what I ended up using as a "hack". I don't want to ignore the warning and would rather accept a hokier syntax (and yes someone is going to say this will kill performance :))
What I use as a workaround is to use a client side addition at the end. For me this error occurred on defining an "integer" constant, so
window.foo = #(Model.Something);
gave me the good old semicolon error. I simply changed this to:
window.foo = #Model.Something + 0;
(In the stated questions case you should just be able to add '', so + ''.
I know there is a whole another addition happening on the client and it isn't elegant, but it does avoid the error. So use it or don't, but I prefer this over seeing the warning/error.
If someone knows of a server-side syntactical workaround for this I would prefer this to the client-side one, so please add.
I found that wrapping the Razor syntax in a JavaScript identity function also makes the IDE happy.
<script type="text/javascript">
#* I stands for Identity *#
function I(obj) { return obj; }
$().ready(function(){
var customer = I(#Html.Raw(ViewBag.CustomerJSON));
});
</script>
This worked for me:
var customer = #Html.Raw(ViewBag.CustomerJSON + ";")
Here's a workaround for booleans:
var myBool = #(Model.MyBool ? "true;" : "false;")
This worked for me
#Html.Raw(string.Format("var customer = {0};", ViewBag.CustomerJSON));
<script type="text/javascript">
$().ready(function(){
var customerName = ('#ViewBag.CustomerName'); // <- wrap in parens
});
</script>
Isn't it as simple as wrapping in parentheses? Putting values through the console seem to work fine with no side effect.
It works for strings, but it still gives the error for non-quoted values, but I still like this for string values. For numbers you could just use parseInt('#Model.TotalResultCount', 10).

IE Object doesn't support this property or method

This is probably the beginning of many questions to come.
I have finished building my site and I was using Firefox to view and test the site. I am now IE fixing and am stuck at the first JavaScript error which only IE seems to be throwing a hissy about.
I run the IE 8 JavaScript debugger and get this:
Object doesn't support this property or method app.js, line 1 character 1
Source of app.js (first 5 lines):
var menu = {};
menu.current = "";
menu.first = true;
menu.titleBase = "";
menu.init = function(){...
I have tested the site in a Webkit browser and it works fine in that.
What can I do to fix this? The site is pretty jQuery intensive so i have given up any hope for getting it to work in IE6 but I would appreciate it working in all the others.
UPDATE: I have upload the latest version of my site to http://www.frankychanyau.com
In IE8, your code is causing jQuery to fail on this line
$("title").text(title);
in the menu.updateTitle() function. Doing a bit of research (i.e. searching with Google), it seems that you might have to use document.title with IE.
Your issue is (probably) here:
menu.updateTitle = function(hash){
var title = menu.titleBase + ": " + $(hash).data("title");
$("title").text(title); // IE fails on setting title property
};
I can't be bothered to track down why jQuery's text() method fails here, but it does. In any case, it's much simpler to not use it. There is a title property of the document object that is the content of the document's title element. It isn't marked readonly, so to set its value you can simply assign a new one:
document.title = title;
and IE is happy with that.
It is a good idea to directly access DOM properties wherever possible and not use jQuery's equivalent methods. Property access is less troublesome and (very much) faster, usually with less code.
Well, your line 1 certainly looks straight forward enough. Assuming the error line and number is not erroneous, it makes me think there is a hidden character in the first spot of your js file that is throwing IE for a fit. Try opening the file in another text editor that may support display of normally hidden characters. Sometimes copying/pasting the source into a super-basic text-editor, like Notepad, can sometimes strip out non-displayable characters and then save it back into place directly from Notepad.

why is IE8 loading javascripts incompletely?

I'm running IE8 in normal mode (whatever it is when compatibility is NOT turned on) on WinXP. I'm doing maintenance on a rails app that was written a few years ago. Often when I load a page, and/or refresh a page, it reports different javascript errors. When I look at the errors in the Developer tool, it appears that a javascript file hasn't loaded completely. So the errors are frequently syntax related, such as '}' expected.
Trailing comma in object literal or array declaration? Some browsers accept this without error, IE does not.
// Trailing commas are bad
var someArray = [
"thing",
"last",
];
var someObject = {
one: "thing",
after: "another",
};
As galambalazs suggested in his comment, jslint will pick up problems like this for you.
Cntrl + F your javascript file and look for a rogue "return" statement.
I ran into this problem on older versions of IE. It was never reproducible in a test harness and left no trace in server logs, but consistently affected a very small percentage of IE 6 loads.
The solution was to have the embedding HTML file double check that the JS was loaded.
foo.js:
// do all the real work.
// As the last statement, set a variable indicating completion.
foo_js_fully_loaded = true;
foo.html:
<script src=foo.js></script>
<script>if (!foo_js_fully_loaded) { /* reload the page */ }</script>

Categories

Resources