What do curly brackets mean in a variable declaration? - javascript

What do curly brackets ({}) do in variable declarations, when surrounding multiple pairs of the form integer:string?
For example, what do they mean here?
char = {0:'(',3:') ',6:' - '};
In this case, it's from the following phone number formatting script:
function formatPhone(obj) {
var numbers = obj.value.replace(/\D/g, ''),
char = {0:'(',3:') ',6:' - '};
obj.value = '';
for (var i = 0; i < numbers.length; i++) {
obj.value += (char[i]||'') + numbers[i];
}
}
I believe that the line defining char is the one that's causing it to fail.

This is a Javascript object. Better indented, it would look like this:
char = {
0: '(',
3: ') ',
6: ' - '
}
It's saying that you're making an object with properties 0, 3, and 6 set to the given values. Then, the properties are accessed with char[i], which returns null unless the property is defined -- so for all i except 0, 3, and 6, it'll default to ''. For 0, 3, and 6, it'll take the relevant strings.
Alright, I think I figured out what's 'not working', though again I'd need you to explain what that means before I can be sure.
This line:
obj.value += (char[i]||'') + numbers[i];
will insert undefined in the string if numbers[i] isn't defined, and numbers[i] is only defined for i = 0, 3, or 6. Change the line to this:
obj.value += (char[i]||'') + (numbers[i]||'');
and it should work.

It creates an object:
obj = {0:'(',3:') ',6:' - '};
You have two elements inside your object with keys 0, 3 and 6. You can access them obj[0], obj[3] and obj[6]
Or you can access them in a loop as you did in your example

That is a Javascript object.
In addition to creating objects using a constructor function, you can
create objects using an object initializer. Using object initializers
is sometimes referred to as creating objects with literal notation.
"Object initializer" is consistent with the terminology used by C++.
The syntax for an object using an object initializer is:
var obj = { property_1: value_1, // property_# may be an identifier...
2: value_2, // or a number...
// ...,
"property n": value_n }; // or a string
where obj is the name of the new object, each property_i is an
identifier (either a name, a number, or a string literal), and each
value_i is an expression whose value is assigned to the
property_i.
The rest of this article is available here.

Related

Are all JavaScript object property names (except Symbols) implicitly converted to strings? Even numbers?

MDN states here
JavaScript object property names (keys) can only be strings or
Symbols.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects#object_initializers
However, it is stated here
Additionally, you can use a numeric or string literal for the name of a property or nest an object inside another.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Grammar_and_types#literals
These are seemingly conflicting statements. My question is,
What is MDN documentation actually saying here? Am I missing something?
What is allowed and what is not allowed as property names?
If object property names can only be strings then does that mean numbers get implicitly converted to strings.
The latter is not about keys per se but rather about what can be used as a key in object literals (so that the interpreter accepts a literal in your code) .
Take
var o = {};
var p = {};
o[p] = 1;
What key is used to store 1 in o? It's '[object Object]', as this is just p promoted to a string (p.toString())
On the other hand
var p = {};
var o = { p: 1, 7: 2 };
Despite p being an object, in the object literal { p: 1, 7: 2 }, p is just a string, the key name. The 7 is promoted to string and makes the second key. The two keys are then 'p' and '7'.
However if a key is enclosed in brackets
var p = {};
var o = { [p]: 1, 7: 2 };
its actual value is used, which means that now, o has two keys, '[object Object]' and '7'.
Edit Regaring the question about [object Object]. The default implementation of the .toString() for an empty object returns this exact string, [object Object].
var p = {}
console.log( p.toString() );
Thus, if an empty object is used as a key, the key name is [object Object]. Interestingly, overrding the toString() changes the key to the toString()'s value:
var o = {}
var p = {
toString: function() {
return 'foo bar';
}
}
console.log( p.toString() );
o[p] = 1;
console.log( Object.keys(o) );
In the above example, the indexing object toString() has been overridden to provide an alternate value (foo bar) and thus, using p as an index creates foo bar key in o (which is shown by calling Object.keys(o)).
Yes, number keys are converted to strings.
const obj = {2: "hello"}
const keys = Object.keys(obj)
console.log(keys)
console.log(typeof keys[0])
console.log(obj[2])
console.log(obj['2'])
// that's true for arrays too
const arr = ["world"]
console.log(Object.keys(arr))
console.log(arr["0"])

Eloquent Javascript - Chapter 4 on The Arguments Object

I know there are a ton of EloqJS questions on here, but I haven't seen this one asked and it is throwing me for a loop. I'm curious how the key squirrel in the object entry (squirrel: squirrel) is not replaced by the argument passed by the function in this code:
function addEntry(squirrel) {
var entry = {events: [], squirrel: squirrel};
for (var i = 1; i < arguments.length; i++)
entry.events.push(arguments[i]);
journal.push(entry);
}
addEntry(true, "work", "touched tree", "pizza",
"running", "television");
I would expect for it to entry to be {events: [], true: true}, but that is not what this is returning. What am I obviously missing here? Original code at http://eloquentjavascript.net/04_data.html#arguments_object
Because object keys are literals: they don't change at runtime or act as variables to be replaced with a value.
If you look at the object initialiser section of the spec (11.1.5), it specifies that an object literal consists of a property name/value list, with property name defined to be one of:
IdentifierName
StringLiteral
NumericLiteral
The rules for IdentifierName are defined in section 7.6 to include most unicode characters, but not reserved words or whitespace.
Any IdentifierName can be wrapped in quotes to become a valid StringLiteral, although the inverse is not always true (StringLiterals containing punctuation or whitespace need the quotes to be valid). You can define the object just as well with:
{'events': [], 'squirrel': squirrel}
As of ES6, there is now a notation to specify that a key should be the value of a variable rather than an identifier or literal of its own. This is defined in section 12.2.6 as a ComputedPropertyName, using the [expr] syntax. For the object to have a true: true property, you could use the ES6 code:
{'events': [], [squirrel]: squirrel}
That's because Object Literal Notation can't receive variables as object keys.
For example:
var name = "John";
var person = {
name: name
}
// person = { name: "John" }
var name = "John";
var person = {};
person[name] = name;
// person = { "John": "John" }

Javascript: What is the difference between usage of . and : operators for specifying a variable in a function or object?

For using a static variable in javascript functions I found out two ways, using . and : operator.
When using . operator we have to specify variable with "f.variable" and when using : we have to use "this.variable". what is the difference between the usage of these two operators.
function f(){
f.a += 1;
this.b += 1;
console.log("f.a: ", f.a);
console.log("this.b: ", this.b);
}
f.a = 0;
f:b = 0;
also we cannot use : when using that variable outside its function like:
function g(){
f:b = 0; //this works fine.
var c = f:b; //raises error invalid label.
console.log(f:b);//but this raises an error missing ')'.
}
Same is the case when we use var to create objects.
var obj = {
a: 2,
b: 3
}
//accessing a and b is done using obj.a & obj.b
//but here
obj:a = 4;
console.log(f.a); // this gives 2
//and similarly using obj:a as rhs value gives error.
How are these two operators used actually.
EDIT:
What is the difference between these two types of variables created.
This:
f:b = 0;
is interpreted as a label, "f", before an expression statement, b = 0;. The ":" is used in object literal syntax to separate a property name expression from its value expression. Otherwise, it is not used for referring to properties of objects.

JavaScript "x in obj": obj.x is undefined?

The following code :
var obj = {uname:"OdO", age:"22"};
alert(obj.uname);
results in:
OdO
Now, using the same concept in a for..in statement :
for (x in obj) {
document.write(obj.x+"<br>");
}
I expected it to print the following:
OdO
22
but it prints :
undefined
undefined
And to achieve printing looping in the elements, it should be written as an array elements like this:
for (x in obj) {
document.write(obj[x]+"<br>");
}
Then, why the first syntax doesn't work, however it works out of the for..in statement ?
When you write obj.x, this literally looks for a property named "x" in obj — just like obj.size would look for a property named "size". x is not defined for your objects, so it comes out as nothing. The correct way of writing it — obj[x] — uses the variable x to look up a property in the object. The bracket syntax uses the value inside the brackets to look up the property, while the dot syntax turns the property name into a string. So these two are equivalent:
obj.x
obj["x"]
So when you write x after obj., it converts that x into a string — it's not a variable anymore.
The bracket syntax is used to receive a property whose name is the expression (expression can be a literal, a variable or something more complex):
var x = "a";
{a:0, b:1}[x] == 0;
The dot syntax is used to receive the property with exactly that name:
({a:0, x:1}).x == 1;
In your for-in-loop, the variable x holds the property name. You are trying to acess the property named "x", which is not defined.
Use the bracket form (obj[x]) when the property name is stored in a variable named "x" and the attribute form (obj.x) when the property name is literally "x".
For example:
var o = {foo:1};
o.foo; // => 1
var x = 'foo';
o[x]; // => 1, since x='foo' and has a property named "foo".
o.x; // => undefined, since "o" has no property named "x".
Try
for(var x in obj){
console.log(obj[x]);
}
This works for me:
var obj = {uname:"OdO", age:"22"};
for (x in obj) {
document.write(obj[x.toString()] + "<br>");
}​
http://jsfiddle.net/zA8HB/

How to get the value of key a and 'a' in javascript

How to get the value of key a and 'a' in javascript?
var obj = {a:1,'a':2}
The first key a will be overwritten by the second 'a'.
obj.a will return 2.
If your key name is a valid Javascript identifier or a number, Javascript will allow you to omit the quotes in key names. In practice, however, it's probably better to train yourself to always use quotes, to avoid confusion like this, and also because JSON requires them.
You can't - they are same key, and that initialiser will create an object with a single element 'a' with value '2'. Try this:
var obj = {a:1,'a':2};
for ( var i in obj )
{
alert(i + '=' + obj[i] );
}
And you'll just get "a=2' in response.
obviously, 'a' is the one-character string with a lowercase a as content; but what do you expect to be the other key? if you want it to be the value of a variable called a, then the curly braces syntax won't help you. Unlike Python, this syntax assumes the keys are strings, and quotes are optional.
You'd have to do something like this:
var a = 'givenkey'
var obj = {}
obj[a] = 1
obj['a'] = 2
this would create an object equivalent to:
var obj = {'givenkey':1, 'a':2}
If you not sure about key - use iteration
for(var k in obj)
alert(k + "=" + obj[k])
When you know key exact value use obj[k]
There isn't any difference.
alert([
obj.a,
obj['a']
].join("\n")); // returns 2 in both cases

Categories