Cross Browser Valid JavaScript Names - javascript

Before you quickly post with "RTFM" or with a bunch of links I have visited, I am fully aware of the documented reserved variable names not to use.
The best lists I could find are here:
http://es5.github.com/x7.html#x7.6.1.1
and
http://www.javascripter.net/faq/reserved.htm
What I am asking for are the variable names that are invalid on 1 or 2 browsers only.
For example I can define print but this will cause an error as print is already defined on the global scope window. Why isn't this documented as a reserve keyword?
Is there a big list of variable names to avoid?

What I am asking for are the variable names that are invalid on 1 or 2 browsers only.
If any such words exist, that browser would be non–compliant with ECMA-262. Only the reserved words in ECMA-262 are "invalid variable names" (provided the name is otherwise compliant with the criteria for variable names, such as allowed characters).
Why isn't [print] documented as a reserve keyword?
Reserved words can only be defined by standards that have a concept of reserved word, the only standard relevant to scripting DOMs in browsers that has that concept is ECMA-262. And it doesn't list print as a reserved word, so it isn't one.
There are various DOM standards that define host objects and their properties, the closest they might get to the concept of reserved word is that of a read–only property, or one that is not writeable. window.print is defined in HTML5, which doesn't define it as not being writable or that it should throw errors if assigned to or attempts are made to modify it. So it doesn't exhibit any behaviour approaching that of a reserved word.
Is there a big list of variable names to avoid?
No, because there aren't any. However, host objects (like window) have default properties that are writeable, you should avoid overwriting them. They should be listed in various places, like the HTML5 specification and browser vendor documentation.
e.g. the following links for the window object:
W3C HTML5 window object: http://www.w3.org/TR/html5/browsers.html#the-window-object
MDN window object: https://developer.mozilla.org/en/DOM/window
MSDN window object: http://msdn.microsoft.com/en-us/library/ms535873(v=vs.85).aspx
In addition, there is a simple for..in loop (per Berji's answer) to discover the enumerable properties at a particular time, however that may not be a comprehensive list of all possible property names and will include user defined properties along with default browser properties without distinction.
It is a better strategy to adopt a naming convention that avoids likely property names and minimise the use of global variables (i.e. user defined properties of the window object).

If you want a big list of browser-defined variables to extend the official list of reserved keywords, type the following into your console on an empty page (about:blank):
>>> Object.getOwnPropertyNames(window)
>>> Object.getOwnPropertyNames(Object.getPrototypeOf(window)) // sometimes not Object
which will yield an Array of strings you definitely should not use. It includes "print", too.
Yet it will be browser-dependent, because some do not implement all the cool HTML5-drafted stuff that uses the Window interface; e.g. you won't find "Worker" in IE9, "openDatabase" in FF and so on. Also, it might not list legacy properties like "onload", altough you will be able to to get a property descriptor for it (and "onload" in window === true).

Related

Global "window" object

The global window object stores properties specific to the environment (for example, window.innerHeight).
But if we print window to the console, we will see the properties highlighted in a different color.
These include Array, Object, and so on, although i thought they are internal objects.
I have a few questions:
What are these "implicit" properties?
Where do JS boundaries end and environment begin?
Can I refer to Array in Node.js, for example?
Thank you.
In the early days of Javascript, there was one master global symbol and everything that was available in the global scope whether it was part of the language itself or part of the browser environment was a property of that master global.
In the browser, that master global is the window object. Thus, you see many things on the window object that are available globally like the Array constructor.
I would guess that this is a side effect of that fact that Javascript was first designed to run in a browser and was not initially a completely stand-alone language with a stand-alone specification.
More recent revisions to the language specification are not adding some new things to the window object any more. For example, when you declare an ES6 class such as:
class Foo {
constructor(greeting) {
this.greeting = greeting;
}
}
You will not find Foo on the window object even though it may be globally available in the browser.
As others have said, the color difference in the debug output has to do with whether the symbols are enumerable or not which is a technical distinction on whether the property shows up in something like Object.keys() or a for/in loop. The property is still there and is accessible either way.

Since when and why dom id names are automatically defined as objects in js api [duplicate]

If I have a <div id='a'> in Chrome then in javascript I can do a.stuff() (it's like as if a is a global variable).
However this does not work with FireFox - I will need to use document.getElementById('a').
What is the correct behaviour here? (according to W3 specs that is)
Also I'm interested in how will Chrome resolve the ambiguity if I have a div with id a yet have a global variable called a too in my script. Is the behavior going to be random and whacky?
And how would an element with id consisting of hyphens ("-"), colons (":"), and periods (".") be translated (ok i know they can be accessed with document.getElementById but how will the browser translate it into the global variable that was representing them)
It depends on which spec you read. :)
This behavior is not described by the HTML4 specification (c.f., http://www.w3.org/TR/1999/REC-html401-19991224/struct/global.html#adef-id and http://www.w3.org/TR/1999/REC-html401-19991224/types.html#type-name). However, it was introduced by Internet Explorer and then copied in other major browsers for compatibility. FireFox also displays this behavior, but only in quirks mode (and even then its implementation seems buggy).
The WHATWG HTML spec currently requires this behavior (a bug report requesting it be removed was closed WONTFIX).
Regardless of spec compliance, using the global namespace (i.e., window) for application code is generally considered bad behavior. Consider referencing element IDs using document.getElementById() or jQuery convenience methods (e.g., $("#a")) and using function-scoped variables to avoid introducing new variables into the global namespace.
There is a longer discussion of this behavior on the WHATWG mailing list.
Since very early days, IE has created global variables that reference elements by their name or id attribute value. This was never a good idea, but was copied by other browsers in order to be compatible with sites created for IE.
It is a bad idea and should not be copied or used.
Edit
To answer your extra questions:
...how will Chrome resolve the
ambiguity if i have a div with id a
yet have a global variable called a
too in my script.
In IE (which introduced this behaviour) if a global variable is declared with the same name as an element id or name, it will take precedence. However, undeclared globals don't work that way. It shoudn't take much to test that in Chrome (I have but I'm not going to give you the answer).
And how would an element with id
consisting of hyphens ("-"), colons
(":"), and periods (".") be translated
(ok i know they can be accessed with
document.getElementById but how will
the browser translate it into the
global variable that was representing
them)
Exactly the same as any object property name that is not a valid identifier - square bracket notation (i.e. window['name-or-id']).
Technically, this question is opinion, but it's a good question.
IE does this as well and it has caused headaches for some.
The rules for naming variables in JavaScript and IDs in HTML are different. I can't see how this is a good thing.
For instance, on this page there is an element with an ID of "notify-container". That's not a valid JavaScript name at all.
Also, when are these names bound? If an inline script declares a variable and then the element appears later, which has precedence?
It's cannot be made consistent.
The worst thing about using elements this way is that they could break at any time if a new API is introduced that has the same name in the global scope.
For example, if you had this prior to the addition of the Performance API
<p id="performance"></p>
<script>
performance.innerHTML = "You're doing great"
</script>
Then that piece of code would've stopped working now in recent browsers that implemented the Performance API as a global performance object was added.
I think document.getElementById is supported by most browsers so far.. Its better and safe using this one..

Understanding Web API DOM interfaces

I'm trying to learn more about Web APIs. Reading about them I see that among the wide variety of web API's there's the DocumentObjectModel API. Reading about the DOM specifications, I find a list of a lot of DOM interfaces. This makes me feel a little upset. In my ignorance, I think that an API should contain only one interface (only one set of functions and properties), here I find a list of interfaces...and that's the first thing that I don't understand.
Moreover, I usually interact with the DOM using notations like
document.getElementById("idname");
document.getElementByTagName("tagname");
etc ect
I see that some of these DOM interfaces have names that I already know, like "Document" or "Window", I use them (like in the previous two lines of code) but I use them not capitalized ("document" rather than "Document"). I don't understand if there is a link beetwen "document" and "Document", for example...
Finally, I noticed that querying for the global object (in the browser console, for example, simply typing the keyword "this") I have in response an object that (I guess) contains all the properties and functions (or methods) of the global object. And among them there are also functions that have the same names listed in the DOM interfaces list. And that's simply another thing that I noticed that I'm not able to explain.
So, can you help me to understand more deeply DOM API?
Those things arise from an interaction of javascript and the DOM specifications.
The capital-letter Window and Document are interfaces defined by the DOM and HTML specs.
In Javascript, when executed in a browser environment, an instance of Window is the global object and Window is its prototype. document and window are getter properties defined by those interfaces. Since the window is the global object (the top-level this) and variable name resolution walks up the scope chain and finally lands at the global object if it cannot find it elsewhere window will eventually resolve to <global object>.window. Which is the attribute defined on the Window interface, which returns the window instance itself, which also is the global object. It is self-referential.
So the global object ends up having properties defined by javascript, by the dom/html specs and inherited from the prototypes also defined by those various specs.
Some prototypes are also exposed as named properties in the global object and not just the prototype chain of the instances. This is convenient for instanceof checks and feature detection. Some constructors are also exposed, e.g. new Image() creates a new instance of HTMLImageElement the same way document.createElement("img") would.
Additional Document instances can created via various constructors or factories such as DOMParser. Additional Window instances might be accessed through frames, the page's opener or spawned child windows.
Looking at the window object with a debugger may help.

Symbol.for(string) in ECMAScript 6

It took me a while but I finally figured out what the purpose of symbols in ECMAScript 6 is: avoiding name collision when attaching properties to shared objects - HTML elements e.g. (In case you're stuck on the same question, I recommend this article.)
But then I stumbled upon Symbol.for(). Apparently ECMAScript 6 will maintain a global symbol registry which you can query with this function by providing the symbol description. Come again? If I use symbols to avoid name collisions, why would I want code other than my own to use them? (*) And how would I avoid name collisions in that global registry? Sharing of symbols seems to completely subvert the concept and a global registry doubly so.
(*) Yes, I know symbols aren't truly private, but that's besides the point.
If you don't want your symbols to be available in GlobalSymbolRegistry, just don't use Symbol.for.
Only use it if you want to allow other codes to use your symbol.
In the following example, I create a symbol to store data in DOM elements. And I may want every other code (e.g. internal raw uncompiled handlers) to read that data. So I make the symbol globally available.
var sym = Symbol.for('storeDataInDOM');
document.querySelector('button')[sym] = 'Hello, world!';
<button onclick="alert(this[Symbol.for('storeDataInDOM')])">Click me</button>
It's like creating global variables: should be avoided in general, but has its advantages. But with symbols instead of strings.
If I use symbols to avoid name collisions, why would I want code other than my own to use them?
That's not the only use case of symbols. The two most important other ones are:
they don't collide with string-keyed properties
they are not enumerated by the usual mechanics
Sharing of symbols seems to completely subvert the concept and a global registry doubly so.
Not necessarily. Right from that article you read: "The registry is useful when multiple web pages, or multiple modules within the same web page, need to share a symbol." The best example for these are the intrinsic symbols - they guarantee interoperability across realms, that's why the global symbol registry is more global than your global scope.
For example you might have a library that is loaded in a web page, an iframe and a web worker. If you share data between those environments (realms), all of the three instances of your library would want to use the same symbol.
There also is a real need interoperability between different libraries, which might not even know about each other. Good examples are transducers, algebraic structures or promises. Would ES6 already be in use, all of these would have agreed on common names in the global symbol registry, instead of relying on strings like these or the then method.
Another good example would be custom hooks defined by your engine, e.g. a Symbol.inspect = Symbol.for("inspect") that you can use to define custom stringification behavior to be used by console.log. Admittedly, that symbol does not necessarily need to be made available through the global symbol registry, it could as well be put on that specific library object (e.g. console.inspect = Symbole("console.inspect")).
And how would I avoid name collisions in that global registry?
Just like you previously did with properties, or global module objects: by using very long, very descriptive names - or by good faith. Also there are some naming conventions.
I invented the most useful feature of Symbol.for() call. If there is using symbols in your code sometimes it is difficult to use conditional breakpoints while debugging. For example, you need to catch if the variable equals the value which is of symbol type and this value binded in the different module. The first difficult way is to use this value as a constant and export it from that module. In this case, the condition of the breakpoint will look:
catchedVariable === exportedSymbolConst
But the easiest way is to temporarily change the code inside the module adding .for to Symbol. Then you can write the condition:
catchedVariable === Symbol.for('string_key')
After the successful debugging you will be changing the code back just removing .for part.

Viable JavaScript Variable Names

This is a two part question: General, and Specific.
For the general: I often find myself wondering what constitutes a viable variable name in JavaScript? I know there are certain 'words' that can not be used as variables in JavaScript; But I have yet to come across either a list of non-viable variable names, or a rule to apply when creating a variable name. I usually err on the side of caution and use obscure names if I am unsure.
It would be nice to know, with certainty, what can be used as a JavaScript variable, and what can not be used.
Any advice?
For the specific: I am wondering if I can use href as a variable name in my JavaScript? Is it viable, or is it reserved?
Afterthought: Perhaps I can extend this question to encompass JavaScript function names as well. What names are viable, and which are reserved? If the two questions are related, I will edit to ask both.
Note: I am not asking which characters can be used in a JavaScript variable; That question is already answered here.
Uhm, actually, you can use any kind of name as a variable name.
Instead of referring to the variable by name, refer to it by array index, since all object properties in JS can be accessed by index*, as well as the fact that global variables are simply properties of the window object.
*a string index can contain literally any kind of character sequence
So the question in turn might be more on the lines of "should I use reserved words as variable names?"
Common sense would say you shouldn't, except when such a name is actually related to the construct and you can't find a suitable replacement.
window['function'] = 2;
window['if'] = 4;
window['var'] = 8;
alert(window['function'] + window['if'] + window['var']);
Warning!
Reserved words are different from native functionality.
Although in many cases you can use names used as reserved keywords as variables, native functionality can actually be overwritten.
For instance Mr Sarris above mentioned Node, (which is a native function not a reserved keyword), you can actually overwrite it by doing window['Node'] = myNewThing;. This has been used in some cases to achieve "wrapper" or "hotfix" functionality, but it is not guaranteed to work in a cross-browser manner (eg; MSIE's console object).
You can find lists of reserved words in JavaScript.
href is certainly fine as a variable name because href is an attribute of an a tag and in no way conflicts with JavaScript naming.
If you are ever in doubt as to whether or not a variable is already in use you can always open the developer tools (F12 in most browsers), go to the console, and type in the name. In this case you'll get:
> href
x ReferenceError: href is not defined
Nothing is using it, so it is yours to use without problem.
Just for kicks if you did enter a reserved word it would look like:
> finally
x SyntaxError: Unexpected token finally
Or if it was a native but already taken word it might look like:
> Node
function Node() { [native code] }
(Node is already defined, and its a native function)
Every programming language has a list of reserved words.
These reserved words consist of the parts that constitute that programming language.
For JavaScript, things like for or function or if are reserved words, since these have special meaning in the language itself. As a rule of thumb you cannot re-use words as identifiers (names) that already have a meaning in that particular language.
The official language specification is a good place to look that up. For JavaScript see the ECMAScript specification, section 7.6.1 (section 7.6. clarifies the other rules that apply to identifier naming).
Your question whether href is okay to use in JS is easily answered by looking there.
rules for variable declaration (on codelifter)
href is ok to use

Categories

Resources