Why is swapping characters this way valid JavaScript? - javascript

I am getting confused on how this snippet of code works. I would assume that the A would need to be 'A' in order for these two characters to swap, but it works. Also, is there a name for what this is doing? From the looks of it, I think it is destructuring, but I'm not certain.
var translations = {
A : 'U'
};
console.log(translations['A']); //returns U
I would have assumed you need to write it this way:
var translations = {
'A' : 'U'
};
console.log(translations['A']); //also returns U
https://jsfiddle.net/ud37asp8/14/

Object or property keys can be either an identifier name (i.e. identifiers + reserved words), a string literal, or a numeric literal. It does not really matter whether you call it A or 'A' in the way of accessing it. https://ecma-international.org/ecma-262/6.0/#sec-object-initializer
Property names
Property names must be strings. This means that non-string objects
cannot be used as keys in the object. Any non-string object, including
a number, is typecasted into a string via the toString method.
var object = {};
object['1'] = 'value';
console.log(object[1]);
This outputs "value", since 1 is type-casted into '1'.
var foo = {unique_prop: 1}, bar = {unique_prop: 2}, object = {};
object[foo] = 'value';
console.log(object[bar]);
This also outputs "value", since both foo and bar are converted to the
same string. In the SpiderMonkey JavaScript engine, this string would
be "['object Object']".
Also what you are doing is basically creating an Object. I do not see you destroying it anywhere.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer
Creating objects
However, the advantage of the literal or initializer notation is, that
you are able to quickly create objects with properties inside the
curly braces. You simply notate a list of key: value pairs delimited
by comma. The following code creates an object with three properties
and the keys are "foo", "age" and "baz". The values of these keys are
a string "bar", a number 42, and another object.
var object = {
foo: 'bar',
age: 42,
baz: {myProp: 12}
}
Accessing properties
Once you have created an object, you might want to read or change
them. Object properties can be accessed by using the dot notation or
the bracket notation. See property accessors for detailed information.
object.foo; // "bar"
object['age']; // 42
object.foo = 'baz';
One can think of an object as an associative array (a.k.a. map,
dictionary, hash, lookup table). The keys in this array are the names
of the object's properties. It's typical when speaking of an object's
properties to make a distinction between properties and methods.
However, the property/method distinction is little more than a
convention. A method is simply a property that can be called, for
example if it has a reference to a Function instance as its value.

Related

removing an arbitarry property from an object, when said property is abstracted as a string

Let's say I have an object myObject with properties a,b,c.
If I want to get rid of property a, I can normally use:
{a, ...rest} = myObject;
And then work with rest, so I can avoid object mutation.
However, I'm dealing with a situation where the name of the property I want to get rid of is abstracted as a string parameter. I can still access said object's property using the brackets syntax, so if:
const stringWithThePropertyName = 'whatever';
then the property would be :
myObject[stringWithThePropertyName]
and that would be equivalent to myObject.whatever
. But what if I want to remove said property from the array?
That is to say, given an object, removing an arbitrary property whose name I take as a string parameter, preferably in an immutable way as I would with the usual spread + destructuring sintax.
You can use bracket syntax while destructuring if you define a variable name to put the found value into:
const myObject = {
foo: 'foo',
bar: 'bar',
baz: 'baz'
};
const stringWithThePropertyName = 'foo';
const { [stringWithThePropertyName]:_ , ...rest } = myObject;
console.log(rest);
(the _ variable will contain the value at foo, so if you just want the object without foo, just don't use the _ variable)
Note that this doesn't actually remove the property from the object - it only creates a new object without that property (which is perfectly fine - avoiding unnecessary mutation is often a good idea). If you actually want to remove the property from the original object, use delete:
delete myObject[stringWithThePropertyName];

Javascript arrays?

This may be completely stupid but given I type this into my browser console:
var arr = [];
arr.item = 'val';
console.log( arr );
arr;
What is the arr; syntax doing behind the scenes? I'm assuming console.log( arr ); is iterating all the properties of the arr object but what is arr; doing? Also does [] tell me I'm dealing with an object of type array and {} tells me I'm dealing with an object of type object literal? So [ item: 'val' ] is an object with a prototype of array and { item: 'val' } is an object of prototype object literal?
Edit: Another way to ask this might be why are console.log and arr; different?
Sorry, started to type the comment and realized it was actually a full answer.
console.log yields an implementation dependent string representation of the argument. It does not iterate the properties of an object in most I've seen. String serializtions using the default toString method look like [object Foo] where 'Foo' is the internal class property of the object. You can see this for arrays by using Object.prototype.toString.call([]);.
The last line on the other hand, is just the value. How that gets represented as an evaluated expression in your browser console is implementation-dependent, but for all intents and purposes it does nothing and there is no reason you would want to write that.
Note that adding a property to an array with the . operator is almost never what you want: it does not add to the contents of the array but treats the array as an object. Iterating the indicies of the array will not yield that property, nor will its methods such as .map include it. Use .push. If you want string-keyed properties, use an object.
What is the arr; syntax doing behind the scenes?
This is an ExpressionStatement. The JavaScript engine tries to evaluate the expression by reading the value of the variable, and then does nothing with it. If it occures inside a javascript function, it will do nothing (except when arr is not a variable, it will throw an error). If you just write arr; into the developer console, most browsers will echo the value of the last typed in expression, so you will see the value of arr as a result. The echoing mechanism is often implemented similar to console.log;
I'm assuming console.log( arr ); is iterating all the properties of the arr object
console.log prints a value to the developer console. If the value is a string, then the string gets printed. If the value is an object, then it is browser-dependent what happens. Most browsers, like Chrome will show an interactive representation of the object, like this:
Other browser might just call toString on the object, which in fact will iterate over the elements, and join them by commas.
Also does [] tell me I'm dealing with an object of type array and {} tells me I'm dealing with an object of type object literal?
Yes and yes. [1, 2, 3] is an array literal, which will evaluate to a new instance of an array containing those values. [] is just an empty array. Arrays are instances of the type Array. {a:1,b:2} is an object literal, will evaluate to a new instance every time. {} is an empty object with no fields. Object literals evaluate to instances of the type Object.
So [ item: 'val' ] is an object with a prototype of array and { item: 'val' } is an object of prototype object literal?
No and yes. [ item: 'val' ] is invalid syntax. Array literals have elements separated by commas, they cannot have colons in them.
[ item: 'val' ]
VM154:1 Uncaught SyntaxError: Unexpected token :(…)
The : is the unexpected token, the expression can't be evaluated because it has syntax errors.
On the other hand { item:'val' } is a completely regular object literal with type Object and will have a single field named item with value 'val'.
About object properties
In javascript, object do not have a fixed set of properties. Properties can be dynamically added and removed by writing them and by using the delete keyword. Every object has string (or Symbol) field names. An array can be seen as an object, optimized for integer keys. But still, keys are strings, so a[0] means the same as a["0"].
var arr = [1, 2];
arr.item = 'val'; // assigns a new field to the object, called item
arr['item'] = 'val'; // does exactly the same as the previous
arr[1] = 3; // sets the second item in arr to 3
arr['1'] = 3; // does exactly the same as the previous
console.log(arr);
// prints [1, 2, item: "val"]
So arbitrary named fields can be assigned on an array, and when printed, Chrome does notice the object being an array, so uses array notation, but also prints the 'other' assigned values. It's important to mention that not every field gets printed, as arr.length is a fully featured property. It is the way guys at Google chose to print arrays. It is not a valid JavaScript syntax, it is just a (pretty good) visualisation of data inside an array.
About classes and prototypes
We say that foo is of class Foo if foo has the prototype Foo.prototype, in other words foo.__proto__ === Foo.prototype. Here foo is an object, Foo is a constructor function. As Foo itself is a function, Foo.__proto__ === Function.prototype.
If subtypes are involved, then we can say bar is an instance of Foo, if bar has Foo.prototype in it's prototype chain, i.e.: bar.__proto__ === Foo.prototype || bar.__proto__.__proto__ === Foo.prototype || .... Explicitly accessing an object's .__proto__ property is considered a bad practice and is strongly discouraged. Altering the __proto__ value leads to serious performance drop, because it breaks the browser's optimisation strategies. So how to check if an object is of a type? You can use the instanceof operator.

Accessing an array element inside JSON Object

Unintentionally, In my project I had used the following code and I was surprised to see that is working:
HTML
<span id="output"></span>
Javascript
var myObject = {
'a': '----First---',
'b': '----Second---',
'c': '----Third----'
};
var myArray = ['a'];
// First Case
output.innerHTML = myObject[myArray];
var myArray2 = ['b'];
// Second Case
output.innerHTML += myObject[myArray2];
var myArray3 = ['a', 'b'];
// Third Case
output.innerHTML += myObject[myArray3];
Output
----First-------Second---undefined
Jsbin Link: http://jsbin.com/godilosifu/1/edit?html,js,output
I am directly accessing array reference within Object which should be undefined in all the cases but strangely When array is of Size 1, it always gets the first element and use that as the object key.
I just want to know what is this concept called and why is this happening ?
Because the property name has to be a string, it is type cast into one using the toString() method. The reason that your third example is undefined is that ['a', 'b'].toString() equals 'a,b', which is not a property in your object.
Property names
Property names must be strings. This means that non-string objects
cannot be used as keys in the object. Any non-string object, including
a number, is typecasted into a string via the toString method.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Property_Accessors
Worth noting is that in ECMAScript 6, there is a new collection type called Map, which allows you to use any object as a key without type coercion.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map
When you pass the array to the object as a Key, it is calling toString() on it. This is because all Keys in Javascript are Strings.
['a'].toString() is "a"
myObject['a'] is "----First----"
See: Keys in Javascript objects can only be strings?
It's auto-casting. In Javascript, only strings can be indexes into an object's properties. myObject is not an array, it's an object. Even though you're using the brackets to access it's properties, it is not the same meaning as brackets used on an array object.
Due to object properties only being allowed to be named by strings, the compiler auto-casts your array to a string (essentially calling it's native toString() function, which for an array, joins all the elements with a comma).
So when you pass your array to the object's property accessor/index, it does this:
myArray1 ==> "a";
myArray2 ==> "b";
myArray3 ==> "a" + "," + "b" ===> "a,b";

Associative array versus object in JavaScript

In my script there is a need to create a hash table, and I searched in google for this. Most of the folks are recommending JavaScript object for this purpose. The The problem is some of the keys in the hash table have a "." in them. I am able to create these keys easily with the associative arrays.
I don't understand why associative arrays are bad. The first thing that is mentioned on the sites that I looked at is the length property.
I am coming from the Perl background, where I used hashes. Most common uses were to get the value from a key, check if a key exists, delete a key-value pair, and add a key-value pair. If these are my common uses, can I safely use an associative array?
In JavaScript, objects are associative arrays...there aren't separate concepts for them. You are also able to safely use '.' in a key name, but you can only access the value using the bracket notation:
var foo = {}
foo['bar'] = 'test';
foo['baz.bin'] = 'value';
alert(foo.bar); // Shows 'test'
alert(foo['baz.bin']); // Shows 'value'
If you're using them already and they work, you're safe.
In a JavaScript, an object and array are pretty much the same thing, with an array having a bit of magical functionality (autoupdating the length property and such) and prototype methods suitable for arrays. It is also much easier to construct an object than using an associative array:
var obj = {"my.key": "myValue"};
vs.
var obj = [];
obj["my.key"] = "myValue";
Therefore never use the array object for this, but just the regular object.
Some functionality:
var obj = {}; // Initialized empty object
Delete a key-value pair:
delete obj[key];
Check if a key exists:
key in obj;
Get the key value:
obj[key];
Add a key-value pair:
obj[key] = value;
Because there is no such thing as built-in associative arrays in JavaScript. That's why it's bad.
In fact, when you use something like:
theArray["a"] = "Hello, World!";
It simply creates a property called "a" and set its value to "Hello, World!". This is why the length is always 0, and why the output of alert(theArray) is empty.
Actually, an "associative array" is pretty much the same as an "array-like object" in ECMAScript. Even arrays are objects in ECMAScript, just with the exception to have numeric keys (which are still strings in the background) and a .length property, along with some inherited methods from Array.prototype.
So, a Perl hash and an ECMAScript object behave similarly. You might not know that you can access object properties not only via a dot, but also with brackets and strings, like
var myObj = { foo: 42 };
myObj.foo; // 42
myObj['foo']; // 42
Knowing that, you can also use keys with .
var myObj = { };
myObj['hello.foo.world'] = 42;
Of course, you can access that key only with the bracket notation.
You can use . in key names on JavaScript objects (AKA associative arrays) if you'd like; they're accepted without issue. The minor drawback is you can't use shortcut notations with the dotted keys, e.g.
var x = {};
x['hello'] = 'there';
alert(x.hello);
is perfectly acceptable and will pop up an alert with 'there' in it. But if you use a dotted name:
var x = {};
x['this.is'] = 'sparta';
alert(x.this.is);
will fail, as JavaScript will look for an attribute named this in the x object, which does not exist. There is only the this.is attribute.
There isn't an associative array. It's just an object.
foo.bar; // Equivalent to...
foo["bar"]; // Looks like associative array.
For the sake of convenience of using data, there should be no difference between an object and an array. You can think of it as an object or you can think of it as an associative array. At the end, you can just think of everything as data.
For PHP, [ ] accepts 0, 1, or more items(array), and it is called an associative array. It is JSON in PHP's coat:
$data = ["message"=>[ "id"=>405, "description"=>"Method not allowed.", "detail"=>[]], "object" => []];
For JavaScript, { } accepts 0, 1, or more items(array), and it is called an object. This data format is JSON:
data = {"message": { "id":405, "description":"Method not allowed.", "detail" : {}}, "object" : {}};
I just call them data. The simplest way to describe data is JSON, or its variants.

What is the type of "keys" in JavaScript?

I bumbed into one of those moments when I just lose the focus and start wondering on a silly question:
var a = {
b: "value"
}
What is the typeof 'b' and I don't mean the typeof "value", but the actual Key labeled as b?
background:
I started wondering about this when I had to create a key which is a string:
var a = {
"b": "value"
}
because at a later point it is referenced as:
a["b"]
And then ended up wondering about the original question.
In object literal terms, b is a property. Properties are either strings or symbols in JavaScript, although when defining the property name inside an object literal you may omit the string delimiters.
for (key in a) {
alert(typeof key);
//-> "string"
}
Property names are automatically coerced into a string. You can try this yourself by using a numeric literal as a property name.
var object = {
.12e3: 'wut'
};
object[.12e3]; // 'wut'
object['.12e3']; // undefined
object['120']; // 'wut'
// Let’s try another numeric literal:
object = {
12e34: 'heh'
};
object[12e34]; // 'heh'
object['12e34']; // undefined
object[1.2e35]; // 'heh'
object['1.2e35']; // undefined
object[1.2e+35]; // 'heh'
object['1.2e+35']; // 'heh'
For this reason, I’d recommend using only string literals for property names.
From Unquoted property names / object keys in JavaScript, my write-up on the subject:
Quotes can only be omitted if the property name is a numeric literal or a valid identifier name.
[…]
Bracket notation can safely be used for all property names.
[…]
Dot notation can only be used when the property name is a valid identifier name.
I also made a tool that will tell you if any given property name can be used without quotes and/or with dot notation. Try it at mothereff.in/js-properties.
b is a string, it's just a shorthand syntax, so you write
var a = {
b: "value"
}
instead of
var a = {
"b": "value"
}
Keep in mind that JavaScript objects are hash tables and the keys are just strings. You may omit the quotes around property names during declaration, but if you use reserved words for property names or any other name that happens to be an invalid identifier, such as starting with a digit, or containing spaces, you would have to wrap the property names in quotes:
var a = {
"1b": "value",
"b and c": "value",
"+12345": "value"
};
Also note that you can reference the properties of objects using the dot notation or the subscript notation regardless of whether quotes were used when they were declared. However, if you use property names that would be invalid identifiers, such as the ones in the above example, you are forced to use the subscript notation:
a.1b // invalid (dot notation)
a["b and c"]; // valid (subscript notation)
var a = {$ : 'hello', 2123 : 'number'};
for(var key in a) {
console.log(typeof key)
}
Keys in javascript objects can be strings and symbols. symbol is a primitive data type in javascript.

Categories

Resources