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.
Related
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.
In python _ is used as a throwaway variable. Is there an idiomatic accepted name in javascript?
Rigth now, you can use array destructuring, no need for a var.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment
For example:
[,b] = [1,2];
console.log(b);
will output :
2
And the value 1 won't be assigned to any unused var.
There isn't an accepted throwaway variable naming in JavaScript like in Python. Although, generally in the software engineering world, engineers tend to call those variables:
dummy, temp, trash, black_hole, garbage.
Use these variable namings or whatever name that will imply to the engineer reading your code that these variables have no specific use.
With that in mind, I would strongly not recommend using signs such as below as a throwaway variable:
_, $
Unless there is an explicit convention like in Python, don't use these signs as a throwaway variable, otherwise, it may interfere with other naming conventions and libraries in other languages, like the underscore and the jQuery libraries in JS.
And of course, if you find a specific use for that variable later on, make sure to rename it.
Generally, you will declare the signature of a function as an array. Simply omit one of them
const foo = (bar,baz,) => bar+baz;
foo(3,4,5) // → 7
This obviously works as long as the declaration of function argument is the last one; unlike this answer, which is valid for already-declared variables embedded in arrays. This:
const foo = (, bar,baz) => bar+baz;
will fail with:
Uncaught SyntaxError: expected expression, got ','
You can hack your way into this using any expression. However, you'll need to use the self same expression in every invocation
const quux = ([], bar,baz) => bar+baz;
quux(42,3,4); // → Uncaught TypeError: (destructured parameter) is not iterable
quux([],3,4); // → 7
That constant can be anything, so you can as well call it "dummy", but you will still have to repeat in every invocation.
As far as I know you can get map's value by key in two ways:
var myMap = {a: 1, b: 2}
var firstWay = myMap.a
var secondWay = myMap['a']
Which way is preferable? Is there a convection for this? Should I avoid first way and could be there any problems I may find in the future (e.g IE may not support it)? I understand that if I had some keys which require text escaping I won't be able to use .value on the map object, but what about simple cases?
My subjective point of view is that first way looks better.
The difference is that the dot notation requires the property name to be an identifierName. For example:
obj["a-b"]; // ok
obj.a-b; // fail! Parsed as `(obj.a) - b`
Moreover, before ECMAScript 5, the dot notation only allowed identifiers. That is, it excluded reservedWords. Then,
obj.class; // ok in ES5+
obj.class; // fail on old browsers
So in those cases you might prefer the bracket notation.
Otherwise it doesn't matter.
Technically the only difference is that you can use the [property] syntax even if you don't know the property name. E.g.:
property = 'a'
myMap[property] // results in 1
Otherwise just use the dot notation.
Also some people use a convention that you use the dot notation for your own data, but use brackets to access data retrieved from some external source.
var completeObj = {a: { b: { c: { d: { e: { f: 23 } } } } } };
var funcA = function(obj){
var a = 'a',b='b',c='c',d='d',e='e',f='f';
return obj[a][b][c][d][e][f];
}
var funcB = function(obj){
return obj['a']['b']['c']['d']['e']['f'];
}
funcA is much slower than funcB,looking for varible in scope cost so much time?
test url : http://jsperf.com/static-and-dynamic-argument
thx
http://jsperf.com/static-and-dynamic-argument/2
I took your test cases and added one to it to 'prove a point'. When you access somthing in an object via the ['key'] notation, you're doing the same thing as accessing it via .key. The compiler is smart enough to know that ['a'] is equivalent to .a. However, when you stick a variable in there, as Bergi mentioned in his comment, the compiler has no idea that [a] is actually ['a'].
It is because local variables(function-scope) become properties of an internal Variable object. So a call to obj[a][b][c][d][e][f] ends up accessing properties a through f on the Variable object first and then on completeObj.
It has nothing to do with variables or variable scope (pure local variables are actually free) but using reflection to access properties rather than constants.
obj['a']['b']['c']['d']['e']['f'];
is equal to obj.a.b.c.d.e.f so it is known even from the source code what properties will be accessed.
However, using bracket notation with variables requires figuring out at runtime what properties will be accessed and so it's completely different. In Java the former code is like using Reflection library to access properties whereas latter is same as using normal static dot access.
So why doesn't the compiler "realize" that the variables are static too? Well your code is completely unreasonable and JIT wasting time optimizing unreasonable code is a bad JIT.
Why does it realize that ['a'] is same as .a though? Well at least in my experience it was much simpler to have parser spit out same MemberAccess objects for dot and bracket access and then just check if the expression is a constant string.
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.