So You Want to Use JavaScript in The Next Freelance Project —Object (Dictionary)

I still remember the days of debugging CORS problem when I put together some projects using JavaScript (& ajax), “a very particular programming language” in my first impression. Recently I got a great opportunity. The new role uses JS, the browser-side script that is now winning in all sides, as the major language. So I took it as a good chance to learn JS more systematically, and this series will be part of the outcome of my study. As the name implies, I will not cover primary level such as “if, else” (condition), “for” (or any kinds of loops), or basic OOP concepts. Instead, I will focus only on differences so you can learn this versatile language like reviewing a pull request, and use it the next day in your next awesome project.
— Some Basics
— String and Array
— This
— Object (Dictionary)
— Prototype (1)
— Prototype (2)
—Async
In JavaScript, it is hard to differentiate an object and a dictionary (a.k.a., map in some other languages):
var hero = {
name: 'iron man',
birth: 1971,
};alert(hero["name"]);// use map key to fetch property
alert(hero.name);var herodict = {
"name": 'iron man',
"birth": 1971,
};alert(herodict["name"]);
alert(herodict.name);// use property name to fetch a value
Result:
iron man
iron man
iron man
iron man
According to the result, the behavior of objects (those with properties) and dictionaries (those with string as keys) are the same. I will use .
when referring to properties in the rest of text, since object is the official name.
In the above example, the class of an object is defined in a one-off manner. To declare a types (a.k.a., class) that can be reusable, we use constructor or class
(es6).
Constructor
A constructor is a special usage of function, for 1) define a type; and 2)creating an object:
Example:
function StarkIndustries(name, birth) {
this.name = name;
this.birth = birth;
}var iron1 = new StarkIndustries('iron01', 2017);
var iron2 = new StarkIndustries('iron02', 2017);alert(iron1.name);
alert(iron2.name);
Result:
iron01
iron02
As per the code, this special usage is activated by adding new
before an ordinary method. So we can use the method as a constructor that constructs and initialize an object.
Revisit this
issue
Missing new
falls into the this
pitfall, when using a method that is designed as a constructor
var name = "stark";
var birth = 1971;function StarkIndustries(name, birth) {
this.name = name;
this.birth = birth;
}var iron1 = StarkIndustries('iron01', 2017);alert(iron1);
alert(name);
alert(birth);
Result:
undefined
iron01
2017
From the experiment above, we can observe that without new
:
this
insideStarkIndustries()
points towindow
, thus, the outside global variables(name
,birth
) have been tampered within the misused constructor;- the misused
StarkIndustries()
returns aundefine
.
So it is a dangerous operation.
solution 1
A common practice is doing sanity check inside the constructor:
if (!(this instanceof StarkIndustries)) {
warn("StarkIndustries is a constructor and should be called with `new`");
}
solution 2
or use strict mode in which this
is set to undefined
in the above case:
"use strict";
And it is fine if you want to do both. Or, you can use real constructor inside a real class.
Class
Example:
class Hero {
constructor(name, birth) {
this.name = name;
this.birth = birth;
}
}var iron1 = new Hero('iron01', 2017);
var iron2 = new Hero('iron02', 2017);alert(iron1.name);
alert(iron2.name);
Result:
iron01
iron02
What if new
is missed here:
class Hero {
constructor(name, birth) {
this.name = name;// note, here we can still declare properties within constructor
this.birth = birth;
}
}var iron1 = Hero('iron01', 2017);// error: Uncaught TypeError: Class constructor Hero cannot be invoked without 'new'var iron2 = Hero('iron02', 2017);alert(iron1.name);
alert(iron2.name);
The code triggers an error when we are about to create iron1
. So class
is generally safer than the method constructor.
Dictionary
At last, we examine more dictionary facets of an object. In particular, I will show two more operations, add and removal, that can be applied on an object’s properties just like on key-value entries.
function StarkIndustries(name, birth) {
this.name = name;
this.birth = birth;
}var iron1 = new StarkIndustries('iron01', 2017);alert(iron1);
alert(iron1.name);
alert(iron1.birth);iron1.age = 0;alert(iron1.age);delete iron1.age;
alert(iron1.age);
Result:
iron01
2017
0
undefined
Besides the techniques described above, JavaScript provides prototype as a more flexible way to modify class definitions. I will start discussing prototype in the next post.
Thanks for the reading and I’ll see you next time.