I'm trying to work out what is considered valid for the property name of a javascript object. For example
var b = {}
b['-^colour'] = "blue"; // Works fine in Firefox, Chrome, Safari
b['colour'] = "green"; // Ditto
alert(b['-^colour']); // Ditto
alert(b.colour); // Ditto
for(prop in b) alert(prop); // Ditto
//alert(b.-^colour); // Fails (expected)
This post details valid javascript variable names, and '-^colour' is clearly not valid (as a variable name). Does the same apply to object property names? Looking at the above I'm trying to work out if
b['-^colour'] is invalid, but works in all browsers by quirk, and I shouldn't trust it to work going forward
b['-^colour'] is completely valid, but it's just of a form that can only be accessed in this manner - (it's supported so Objects can be used as maps perhaps?)
Something else
As an aside, a global variable in javascript might be declared at the top level as
var abc = 0;
but could also be created (as I understand it) with
window['abc'] = 0;
the following works in all the above browsers
window['#£$%'] = "bling!";
alert(window['#£$%']);
Is this valid? It seems to contradict the variable naming rules - or am I not declaring a variable there? What's the difference between a variable and an object property name?
Yes, objects can be used as maps, and any string can be a property name. As you've discovered, some properties can only be accessed using the bracket syntax.
window['abc']
is accessing a property. It is not a variable, even though it refers to the same value (at the global level) as:
abc
Object property naming rules and variable naming rules are separate. The standard only "reserves" a handful of property names (such as prototype and constructor, IIRC), but other than those, any string goes.
Except when the execution environment (i.e. the browser) decides to add more magic properties, of course. (I hear setting __proto__ breaks some things in quite weird ways)
Every time you create a global variable you create in fact a new member of a global object (which is window in browser environment, global in Node.js, etc.). This is why window.x is exactly the same like (global) var x, this.x or just x.
Understanding JavaScript object like a map is quite right, because: a) you can add a new element dynamically - at any moment; b) the element can have any name - also including special characters, c) you can try to access a non-existing element of an object/map and it is not an error, d) you can remove an element from an object.
If you like to access object members with standard dot notation (eg. a.x) you are not allowed to use any special characters different than _ or $; also the name cannot start from a number. For all other cases you are forced to use square brackets and quotation marks to access object elements.
Related
blah('A');
function blah(letter){
arrayA.push('something');
}
I want to push something to an array where the name of the array is 'array' plus a letter being passed to it.
I can console out 'arrayA' fine:
console.log('array'+${letter})
But if I try to build the array name, the same logic doesn't work:
array${letter}.push('something')
In the browser (where the global objects, functions, and variables become members of the window object) you can create and access dynamically named objects using the bracket notation.
Were you looking for something like this?
function blah(letter){
window['array' + letter] = [];
window['array' + letter].push('something');
}
blah('A');
After this you can access and use the newly created array (arrayA) as usual.
arrayA.push('something else');
In node you can probably achieve this using global instead of window.
Try it and forget it (or replace the 3 occurrences of window with global for testing with node.js):
function test(name,value){
if(!window["array"+name])
window["array"+name]=[];
window["array"+name].push(value);
}
try{console.log(arrayA);}catch(e){console.log("arrayA missing: "+e);}
test("A",10);
try{console.log(arrayA);}catch(e){console.log("arrayA missing: "+e);}
test("A",20);
try{console.log(arrayA);}catch(e){console.log("arrayA missing: "+e);}
window is the global scope in a browser, and generally you should not rely on global variables without a good reason. They lack context (that is why they are 'global'), making it hard to tell where they belong, what they are and where they come from. That is something what most programming paradigms advise against.
The thing also works with node.js, just it has global as global context, you can paste this snippet into https://www.tutorialspoint.com/execute_nodejs_online.php as a test, replace the 3 window-s, and it will work (you can of course wrap it into a proper module too, just that is more work). What is written above against the usage of global variables stays true for node.js too. Do not use the global context especially if you are developing modules.
However, instead of window, the syntax works with any object too, and that would be considered okay:
var obj={};
console.log(obj.something);
obj['some'+'thing']=10;
console.log(obj.something);
So you can freely have your own 'context' object (if you write the var obj={}; line in the top-level of a module, it will be available everywhere in that module, and it will not interfere with the outside world), and create/access its members using this array-like syntax (obj['something']), constructing the names on the fly when necessary.
I'm trying to work out what is considered valid for the property name of a javascript object. For example
var b = {}
b['-^colour'] = "blue"; // Works fine in Firefox, Chrome, Safari
b['colour'] = "green"; // Ditto
alert(b['-^colour']); // Ditto
alert(b.colour); // Ditto
for(prop in b) alert(prop); // Ditto
//alert(b.-^colour); // Fails (expected)
This post details valid javascript variable names, and '-^colour' is clearly not valid (as a variable name). Does the same apply to object property names? Looking at the above I'm trying to work out if
b['-^colour'] is invalid, but works in all browsers by quirk, and I shouldn't trust it to work going forward
b['-^colour'] is completely valid, but it's just of a form that can only be accessed in this manner - (it's supported so Objects can be used as maps perhaps?)
Something else
As an aside, a global variable in javascript might be declared at the top level as
var abc = 0;
but could also be created (as I understand it) with
window['abc'] = 0;
the following works in all the above browsers
window['#£$%'] = "bling!";
alert(window['#£$%']);
Is this valid? It seems to contradict the variable naming rules - or am I not declaring a variable there? What's the difference between a variable and an object property name?
Yes, objects can be used as maps, and any string can be a property name. As you've discovered, some properties can only be accessed using the bracket syntax.
window['abc']
is accessing a property. It is not a variable, even though it refers to the same value (at the global level) as:
abc
Object property naming rules and variable naming rules are separate. The standard only "reserves" a handful of property names (such as prototype and constructor, IIRC), but other than those, any string goes.
Except when the execution environment (i.e. the browser) decides to add more magic properties, of course. (I hear setting __proto__ breaks some things in quite weird ways)
Every time you create a global variable you create in fact a new member of a global object (which is window in browser environment, global in Node.js, etc.). This is why window.x is exactly the same like (global) var x, this.x or just x.
Understanding JavaScript object like a map is quite right, because: a) you can add a new element dynamically - at any moment; b) the element can have any name - also including special characters, c) you can try to access a non-existing element of an object/map and it is not an error, d) you can remove an element from an object.
If you like to access object members with standard dot notation (eg. a.x) you are not allowed to use any special characters different than _ or $; also the name cannot start from a number. For all other cases you are forced to use square brackets and quotation marks to access object elements.
Is it right to declare a method like this?
window['TEST']['myfunction?'] = function(param) {
for(var a in([ param.getElementsByTagName('ol'), param.getElementsByTagName('ul') ]){
found += a.length();
}
return a != 0
? true
: false;
}
I always use to declare method like this
var TEST = function(param){
...
}
But I saw the first declaration in some code. But I am not able to get that. What's the difference in these two type of declaration. Which one is more efficient?
In Javascript, virtually everything is an object meaning that everything has a certain set of properties. You can access or set these properties in a few ways, two of which are relevant here.
The first option is window.foo = 'bar';. Another way to write this would be window['foo'] = 'bar'; The first one is called dot notation, the second one is called bracket notation. Bracket notation has one advantage over dot notation, which is the type of characters you can use. For example window.invalid-foo = 'bar' will not work. window['invalid-foo'] on the other hand does.
Now to get to your question; there is a possibility that when encountering window['TEST']['myFunction?'] the original author of the code has his own framework that checks the global window.TEST object for functions. And iterates through these functions and calls them as way of testing his code.
I would not recommend doing things this way because:
you're polluting the global namespace.
You're creating unnecessary confusion by using a non-standard approach to declaring variables.
Is one way of declaring functions faster than the other? The latter is faster by an enormous amount. We're talking 2 million operations per second versus 1.5 billion operations per second.
window['TEST']['myfunction?'] = takes the global object, gets the object stored in its TEST property, and then assigns a function to its myfunction? property.
Globals and property names with odd characters (like ?) are both generally best avoided.
var TEST = declares a locally scoped variable (TEST) and assigns a value to it. Since it isn't a property of an object, it isn't a method.
Bracket notation and dot notation are interchangeable. As far as I know they execute at about the same speed. Bracket notation does allow you to use characters that are illegal in dot notation.
// eg
var myObject = {}
myObject["var1"] = 1; // bracket notation same as dot notation
myObject.var1 = 1; // dot notation same as bracket notation
myObject["test-me"] = 2; // valid creation of property test-me
myObject.test-me = 2; // will throw an error as "-" is an operator.
// the invalid character will force you to use bracket notion whenever you access the property.
Someone else can answer the second part.
This question already has answers here:
Using the variable "name" doesn't work with a JS object
(4 answers)
Closed 7 years ago.
Lets say we have this code segment :
var name = ["Apples","Oranges","Strawberries"];
console.log(name.length);
This code produces this weird result of 27 !! The issue seems to be with using the variable name as 'name' which seems like a reserved keyword.
But can anyone explain why this weird behavior ?
It refers to window.name, which is the name of the window.
You can use the window's name to target hyperlinks, but it's not typically useful.
More info on window.name: https://developer.mozilla.org/en-US/docs/Web/API/Window.name
Just testing in chrome:
You can't stop var name from being window.name, which is a string. No matter what you set the value to, it will be cast as a string so that it is a valid window name. So, name.length is the amount of characters in the string. It's best to avoid variable or be very careful about them!
As I can see from some of the other comments, this is an odd concept if you're new to it. The concern is over what window.name refers to. window.name is the name of the window. Any use of it is naming the window.
Defending that Chrome's behavior is logical:
If this var document = 'foo' did what it looks like it would do, you would have overwritten window.document - the document object - with a string. That would be quite the problem. name is a property of window just like document and has a use that shouldn't be (and can't be in Chrome) replaced.
In the global scope, when you do var name = ["Apples","Oranges","Strawberries"];, it's the same as window.name = ["Apples","Oranges","Strawberries"];.
window.name must be a string, so it assign ["Apples","Oranges","Strawberries"].toString() to it which is "Apples,Oranges,Strawberries".
What is the scope of variables in JavaScript? is a good start. Basically, when you're declaring name outside of a function, you're actually hiding the window.name value, which is a very, very bad idea (be very careful about any global variables you declare - they are actually values of the window object - including hiding existing values.
As others have said, the fact that Google Chrome forces the type to string is probably a Chrome quirk (although somewhat understandable), but the underlying cause is that you're simply doing something "dangerous" you didn't realize you're doing :)
the window object has a property "name";
if you define 'name' in a closure function you may get 3
you defined var name in the global object, so you just initialized a string obj;
(function(){
var name = ["Apples","Oranges","Strawberries"];
consol.log(name.length);
})()
var name = ["Apples","Oranges","Strawberries"];
the global window.name is a build in string object(reserved), so name.toString() is called when you excuete the line above;
As pointed out by others, in the when you are using the variable named name in the global scope it is treated as window.name.
From experimentation under Google Chrome, window.name gets the value as a string, like so: "Apples,Oranges,Strawberries", This behaviour is because Google Chrome is forcing window.name to be string. This explains why name.length will report 27 as that is the length of the string given.
This behaviour is not present in IE, Opera or Firefox which assing the array ["Apples","Oranges","Strawberries"] and report 3 on `name.length as expected, therefore I guess this is a quirk of Google Chrome.
What are expando objects in javascripts?
For what purpose we need this ? Any complete example will be appreciated
I found 1 article here Javascript: The red-headed stepchild of web development
Well, in javascript, any object is an expando object. What it means is, as the article covers, that whenever you try to access a property1 it will automatically be created.
var myObj = {}; // completely empty object
myObj.myProp = 'value';
The moment you assign myProp a value, the property myProp is dynamically created, eventhough it didn't exist before. In a lot of other languages, such as C#, this is not normally possible (actually C# has just enabled expando object support as well, but that's besides the point). To access a property in a normal class in C#, you need to specify in the class that it does indeed have this property.
1 Not quite correct. See npup's comment below for clarification.
Everything except primitive types(string, number,boolean) are objects and support Key:values structure. properties(keys) can be accessed and set using the dot notation as well as the square brackets.
var myObj = {};
myObj.myProp1 = 'value1'; //works, an expando property
myObj[myProp2] = 'value2'; // doesn't work, myProp2 is an undefined name.
myObj['myProp2'] = 'value2'; // works , an expando property
myObj[2010]= 'value'; //note the key is number, still works, an expando property??
myObj.2010 = 'value'; // FAILS. to use dot notation, key must be a string
An article written in 2007 that uses document.all (as the only way to access elements)? That's a big red flag.
It is just dressing up "You can add properties to an object" with some buzzwords.
We need to be able to do this because otherwise we wouldn't be able to store data, and that would make JavaScript a pretty useless language.
(Everything is an array? No it isn't. And it iterates over an object without a hasOwnProperty wrapper. That isn't safe. Just keep away from the article, it is worse than useless)
JavaScript turns elements with specific IDs of names into expandos of the returned DOM object. It is explained here.