Data Types refer to the ability of JavaScript to identify the kind of a value. In JavaScript, a value falls under one of the following 8 types. One of the fundamental characteristics of a programming language is the set of types it supports.
From the list, first 7 types are called primitive data types. So, we can say in JavaScript all non-primitive values are objects.
Primitive Data Type
A primitive value is not an object and does not contain any methods. As discussed in the previous section, Boolean, null, undefined, Number, BigInt, String and Symbol are primitive data types in JavaScript.
Primitive values are immutable. That means a primitive value once created, cannot be changed.
let a = "Backbencher";
a = "Hello";
console.log(a);
In the above code, in line 1, JavaScript is storing a string "Backbencher"
to a memory location. JavaScript is naming that memory location as a
. This association of a variable name to its memory location is tracked by a lookup table which is internal to JavaScript engine.
In line 2, JavaScript engine is not erasing "Backbencher"
and writing "Hello"
. It cannot be done since primitive values are immutable. It creates a new memory location to store "Hello"
and the lookup table is now mapping the variable name a
to "Hello"
's location.
Since all this is happening internally, for the developer it seems like primitive values can be updated or mutated, which is not true.
Boolean
Boolean represents a logical entity. Logical entities are used to write conditions and enable branching in the program. There are only 2 values in JavaScript that are of Boolean type. They are true
and false
.
// Branching
if (true) {
console.log("I am truthy");
} else {
console.log("I will never be logged");
}
Truthy and falsy values
When we use any data types as a logical entity, JavaScript automatically converts that value to a boolean true
or false
. For example, in the following snippet we use "hello"
as a logical entity.
if ("hello") {
console.log("hello is true");
} else {
console.log("hello is false");
}
Here the output is "hello is true"
. It is because, JavaScript automatically converts a non-empty string to a true
. There are some values, when converted to boolean, results in false
. Those values are called falsy values. They are:
0
-0
null
false
ObviouslyNaN
undefined
""
Empty string
All other values in JavaScript are truthy values.
An empty object
{}
and empty array[]
are truthy values. It is not falsy like an empty string.
The string "false" is a non-empty string. So when it is converted to boolean, it is a truthy value.
Boolean Conversion
We can convert any value in JavaScript to boolean type. This can be done using 2 techniques.
Boolean
function
We can use Boolean
function to convert any values to boolean type.
console.log(Boolean("A string")); // true
console.log(Boolean("")); // false
console.log(Boolean(0)); // false
console.log(Boolean({})); // true
!!
Double negation
In JavaScript !
can be used as a NOT operator. In Mathematics, if we have a number 23
, negating it, results in -23
. Again negating it, reverts it back to 23
. In similar way, in JavaScript when using !
, it negates the value and the output is a boolean value.
Here is an example. A non-empty string is a truthy value. Let us do a single negation first.
console.log(!"hello"); // false
Negating a truthy value resulted in false
. We use !
again to get the boolean converted value.
console.log(!!"hello"); // true
null
null
is a primitive type in JavaScript. There is only one value which is of type null
. And that value is null
. So it turns out that both the type and value is called null
.
null
represents intentional absence of an object. That means, if there is a place where the code expects an object, but we are unable to provide one, then we give back null
. Example: match()
is a string method that returns an array of all matches of a supplied pattern.
const str = "Orange is orange";
const result = str.match(/orange/gi);
console.log(result); // ["Orange", "orange"]
Here the match()
method returned an array. After all, array is a type of object. So, we can say that, result
is always expecting an object. If there was no match found, then there is no object to return to result
. In order to state an intentional absence of an object, match()
method returns null
if no match is found.
const str = "Orange is orange";
const result = str.match(/Apple/gi);
console.log(result); // null
Always use
null
to mark intentional absence of an object. Do not useundefined
in place where we need to usenull
. Even though, it might work, we cannot distinguish if theundefined
returned was intentional or a default return of a function. A function in JavaScript by default returnsundefined
.
undefined
undefined
is a primitive type in JavaScript. There is only one value in JavaScript that is of type undefined
. That value is also called undefined
. So, both the type and value is called undefined
.
A variable which is declared and not been assigned with a value, is by default assigned with the value undefined
. So when we print the value of a variable, if it prints undefined
, the most likely chance is that the variable is declared but not assigned with a value.
var a;
let b;
console.log(a); // undefined
console.log(b); // undefined
Global undefined property
The undefined
value is also stored as a property of global(window
) object. If we list out all the properties of window
, we can see a key named undefined
.
console.log(window.undefined); // undefined
What is the significance of this global property? In JavaScript, it is possible to treat undefined
as a variable name and assign a value.
(function(){
var undefined = "Backbencher";
console.log(undefined); // "Backbencher"
})();
Line 3 prints "Backbencher"
. At this moment, if we do a conditional operation with undefined
, it results in wrong decision. To avoid such errors, we can do the comparision with the global window.undefined
property.
if (myVar === window.undefined) {
// ...
}
We can use window.undefined
safely because no one can update its value; That is because the property undefined
of window
is non-writable, non-enumerable and non-configurable.
window.undefined = "Backbencher";
console.log(window.undefined); // undefined
Determine undefined
To check if a variable is declared and assigned, we can use strict equality(===
) operator.
var a;
if (a === undefined) {
console.log("a is declared");
} else {
console.log("a is declared and initialized");
}
Above solution throws an error if the variable a
is not declared before use.
if (a === undefined) {
// ...
}
Line 1 throws ReferenceError: a is not defined
since a
is not declared.
More safer technique is to use typeof
operator. typeof
does not throw error even if the variable is not declared.
if (typeof a === "undefined") {
// ...
}
typeof
returns undefined
in following cases.
- When the operand is not declared
- When the operand is declared but not assigned with a value
- When the operand resolves to an
undefined
value
Number
In most of the programming languages, integer values and floating-point(numbers with decimal) values are treated differently. The amount of memory used for both types also varies. But in JavaScript, there is no distinction between integer values and floating-point values.
Memory and Range
In JavaScript, both integer and floating-point values are treated in the same way. Therefore, considering the worst case, the memory allocation for a number type should consider floating-point values. Each number in JavaScript occupies 64 bit of memory. The numbers are stored in Double-precision floating-point format as per IEEE 754 standard.
In case of integers, JavaScript can accurately represent all integers between -9007199254740992(-253) and 9007199254740992(253), inclusive. Beyond this range, the precision might lose. Let us try adding one to the maximum range.
console.log(9007199254740992 + 1); // 9007199254740992
The expected output is 9007199254740993
. But the actual output is 9007199254740992
.
Numeric literal
When a number appears directly in a program, it is called a numeric literal. JavaScript supports numeric literals in several formats.
12; // Base 10 integer literal
0xff; // Base 16 integer literal
0377; // Base 8 integer literal
3.14; // Floating-Point literal
6.73e5; // Floating-Point literal
Integer literal
Integers in JavaScript can be represented in 3 ways.
- Decimal
- Hexadecimal
- Octal
Decimal numbers are sequence of digits with base 10. When we say integers, what come to our minds is decimal numbers. Examples:
0;
23 - 46;
100000;
Hexadecimal integers have their base as 16. Hexadecimal integers can have digits from 0 to 9 and alphabets A to F. In JavaScript, we denote hexadecimal integers by placing either 0x
or 0X
before the number.
console.log(0xff); // 255
console.log(0xa); // 10
Even though we log a hexadecimal integer, log
method converts it to a decimal before printing in console.
Some JavaScript engines support Octal format. Octal numbers have there base as 8. A numeric literal is marked as octal by prepending a zero(0).
console.log(077); // 63
In Google Chrome, above line prints 63
. It is supported by Chrome's V8 JavaScript engine. Now prepending a zero to mark a number as octal can lead to unexpected errors. Therefore, octal specification is not there in ECMAScript specification. It is not advised to use octal format because of non uniform support across JavaScript engines.
If we use an octal number notation with a non-octal digit, JavaScript engine does not throw an error. Instead, it simply treats the number as a decimal.
console.log(077); // 63
console.log(099); // 99
Floating-point Literal
Floating-point literals are real numbers that contain a decimal point. They contain an integer part, a decimal point and a fractional part. Some examples:
2.78;
0.912;
Floating-point literals can also be represented using exponential notation. Exponential notation is an e
(or E
) followed by a positive or negative integer. Here is an example:
3.67e5; // 367000
3.67e-5; // .0000367
e5
denotes multiply the number 3.67
with 100000. In the same line, e-5
denotes divide the number 3.67
by 100000.
NaN
NaN
is a predefined global variable which holds a Not a Number value. Sometimes, JavaScript need to tell user that the evaluated result is not a number. NaN is for that purpose.
console.log("hello" * 2); // NaN
console.log(0 / 0); // NaN
So is NaN
a variable or value? It is both a variable and value. It is something like, there is a variable a
which holds the value "a"
. Coming back to NaN, NaN is a global variable. So we can find it as a property of window
object. The value that variable holds is NaN
which is a representation for Not a Number in JavaScript.
console.log(window.NaN); // NaN
There is also a property for Number
object called NaN
. Again, the value of that property is NaN
.
console.log(Number.NaN); // NaN
NaN == NaN
So does NaN evaluates to true
when compared with itself? No. That makes sense because NaN is just a representation of Not a Number. For example, "a"
is not a number. "b"
is not a number. So does that mean that "a"
and "b"
are equal? No. Just like that, NaN is not equal to NaN.
console.log(NaN == NaN); // false
NaN
does not compare true with any value, including itself. So we cannot check if a value is NaN
by comparing it with NaN
. Instead we can compare a value with itself, and if it returns false
, then that value is definitely NaN
.
var x = NaN;
console.log(x != x); // true
We can also find if a value is NaN
by using isNaN()
method. isNaN()
method returns true
if the argument passed to the method is NaN
or a value which cannot be converted to a number.
var x = NaN;
console.log(isNaN(x)); // true
console.log(isNaN("apple")); // true
console.log(isNaN("123")); // false. It can be converted to 123
console.log(isNaN(true)); // false. true can be converted to 1
console.log(isNaN({})); // true
NaN as Variable
As we discussed in earlier section, NaN
is a predefined global variable. In ECMAScript 3, we could both read/write that predefined global variable. But in ECMAScript 5, window.NaN
is read only. It is not possible to edit the value of window.NaN
.
NaN = 46;
console.log(NaN); // NaN
Number Conversion
There are different techniques to convert a non-number data type to number data type.
Multiply with one
*
is an operator in JavaScript to do multiplication. We know that a number multiplied with one returns the same number. Also, since multiplication(*
) applies only to numbers, JavaScript automatically converts all operands of *
operator to number data type. We use this automatic type conversion feature in JavaScript to convert any data type to a number type.
// Boolean to Number
console.log(true * 1); // 1
console.log(false * 1); // 0
// String to Number
console.log("123" * 1); // 123
console.log("abc" * 1); // NaN
// Null to Number
console.log(null * 1); // 0
// Undefined to Number
console.log(undefined * 1); // NaN
parseInt() and parseFloat()
parseInt()
and parseFloat()
converts a string to a number.
parseInt()
function accepts 2 arguments. First one is the string to be converted and the second being the radix. In mathematics, radix is also known as the base. Default value of second parameter is 10.
console.log(parseInt("42", 10)); // 42
console.log(parseInt("42", 8)); // 34
parseInt()
ignores the decimal portion in the string, if present.
console.log(parseInt("42.762", 10)); // 42
parseFloat()
can convert a string to a floating-point number.
console.log(parseFloat("42.762", 10)); // 42.762
Number()
Number
is a global function in JavaScript which can be used to convert any type in JavaScript to a number.
Boolean to number
Number()
can convert a boolean value to a number.
console.log(Number(true)); // 1
console.log(Number(false)); // 0
Number()
converts a true
to 1
and false
to 0
.
null to number
Number()
converts null
to 0
.
console.log(Number(null)); // 0
undefined to number
Number()
converts undefined
to NaN
.
console.log(Number(undefined)); // NaN
String to number
Number()
converts an empty string to 0
.
console.log(Number("")); // 0
Number()
converts a string with number value to corresponding number.
console.log(Number("42")); // 42
console.log(Number("42.765")); // 42.765
If the string contains a non-numeric character, Number()
returns NaN
.
console.log(Number("42abc")); // NaN
If we used parseInt()
in the above case, we will get 42
.
BigInt to number
A BigInt value can be directly passed to Number()
to convert it to a number type.
console.log(Number(42n)); // 42
BigInt
BigInt allows JavaScript developers to have much greater integer representation in their code. The maximum a normal number supports is 9007199254740991(2^53 - 1).
Let us try to increment from the current MAX value.
var num = Number.MAX_SAFE_INTEGER; // 9007199254740991
num++;
num++;
num++;
num++;
num++;
console.log(num); // 9007199254740992
Ideally we expect 9007199254740996 in the console, instead it is printing 9007199254740992. JavaScript is not able to compute beyond that.
BigInt solves this issue. It helps to work on numbers beyond 9007199254740992.
Declaring a BigInt
A number is declared as BigInt by appending n
to the number.
10; // Integer
10n; // BigInt
We can also use BigInt()
function to convert any JavaScript type to BigInt type.
BigInt(23); // 23n
BigInt("23"); // 23n
BigInt(true); // 1n
BigInt(false); // 0n
Trying to convert undefined
, null
or an object to BigInt results in error.
Let us rewrite the code in above section using BigInt.
var num = BigInt(Number.MAX_SAFE_INTEGER);
num++;
num++;
num++;
num++;
num++;
console.log(num); // 9007199254740996n
Type of BigInt
We use typeof
operator to determine the type of a variable or value. When used with a BigInt variable or value, it returns "bigint"
.
typeof 1n; // "bigint"
typeof BigInt(1); // "bigint"
String
In JavaScript, String is a primitive data type. It is used in JavaScript to work with texts.
Here is an example of a string.
"backbencher!";
String is immutable
When we do any operations on a string, it creates a new string. The existing string cannot be mutated.
const str = "hello".toUpperCase();
When .toUpperCase()
is invoked, it does not affect the original string "hello"
. Instead a new string "HELLO"
is created in memory and assigned to str
.
Unicode support
Each character in a string occupies 16 bits to consider Unicode characters. Since JavaScript supports unicode characters, we can use unicodes in our texts. Here we are going to assign a malayalam language word to a variable.
const fruit = "ആപ്പിൾ";
console.log(fruit); // "ആപ്പിൾ"
String literals
A string literal is a string data value that appears directly in a program. To use a string literal in the code, wrap the string value in a matching pair of single quotes(''
) or double quotes(""
) or backticks(``
).
"Backbencher.dev";
"Backbencher.dev"`Backbencher.dev`;
The backtick(``
) syntax was introduced in ES6.
When using double quotes or single quotes, we can write a multi-line string literal using backslash(\
).
console.log(
"Backbencher.dev\
is\
rich"
); // "Backbencher.devisrich"
Even though we write the code in separate lines, the output came in single line. That means, the backslash technique is purely to bring code readability. It does not have a difference compared to writing in one line.
The backtick(``
) syntax by default supports multi-line literals. We do not need backslash to write new lines. Also, the new lines are considered as new lines by JavaScript engine.
console.log(`Backbencher.dev
is
rich`);
and the output is shown in three lines.
"Backbencher.dev
is
rich"
String conversion
Any non-string value in JavaScript can be converted to a string in different ways.
String() function
String()
is a constructor function in JavaScript. It accepts any type as its argument and converts it to a String object.
// Primitive to string
const bool = true;
console.log(String(bool)); // "true"
// Object to string
const date = new Date();
console.log(String(date)); // "Tue Jul 07 2020 12:19:55 GMT+0530 (India Standard Time)"
From the code above, it is clear that String()
function can easily handle primitive or object data types.
toString() method
Any data types except null
and undefined
can be converted to string using .toString()
method.
console.log(true.toString()); // "true"
As you can see toString()
is used as a method using dot(.
) operator. But we know that only objects have properties and methods. So how a primitive type like true
behave as an object?
When JavaScript engine tries to evaluate true.toString()
, it understands that the code is trying to treat the primitive value true
as an object. So internally, JavaScript engine converts true
to its equivalent Boolean
object.
Boolean(true); // Boolean object
Now, Boolean
is a constructor function object in JavaScript, which is inherited from Object
type. That means, any methods in Object
can be invoked from its child objects like Boolean
. Such an inherited method is .toString()
.
Boolean(true).toString(); // "true"
Why null.toString()
and undefined.toString()
do not work?
When we use null.toString()
, JavaScript engine cannot convert it into equivalent Null
object. Same is the case with undefined
. If we try to convert null
or undefined
to string using .toString()
method, it throws TypeError.
null.toString(); // TypeError: Cannot read property 'toString' of null
Adding empty string
In JavaScript, we can concatenate two strings using plus(+
) operator. If one of the operand is a string, JavaScript automatically converts other operand to a string. We can make use of this capability to convert a value to string.
const str = true + "";
console.log(str); // "true"
This technique works with null
and undefined
also.
console.log(null + ""); // "null"
console.log(undefined + ""); // "undefined"
Symbol ES6
Symbol is a new primitive data type introduced in ES6. The Symbol()
function returns a value of type symbol.
Creating symbol variable
A variable of Symbol type is created using Symbol()
function.
const s1 = Symbol();
console.log(typeof s1); // "symbol"
While creating a symbol variable, we can optionally pass a description.
const id = Symbol("UserId");
const name = Symbol("UserName");
"UserId"
and "UserName"
are the descriptions. Descriptions help in debugging. Other than that, there is no impact for description strings.
Symbols are unique
Every symbol value returned from Symbol()
is anonymous and unique. We can consider Symbol()
function as a magic box which throws out a unique toy each time when we open it.
Let us create 2 symbols.
const symbol1 = Symbol();
const symbol2 = Symbol();
Here, we open the magic box 2 times. Now let us see what toy we have received by printing the symbol variables.
console.log(symbol1); // Symbol()
console.log(symbol2); // Symbol()
Both statements print Symbol()
in console. Did you expect a random string? If yes, that is not happening. So, is there any way to see the contents of both variables? No. That is why they say Symbol()
produces anonymous and unique values.
In that case, how can we make sure that both the variables are unique? That is a guarantee by JavaScript. Now for our relief, at least we can try comparing them.
console.log(symbol1 == symbol2); // false
Seeing a false
is assuring. It means symbol1
and symbol2
are unique.
Having same description, does not create identical symbols. Descriptions are purely for debugging purpose. It does not have any impact on uniquness of generated symbols.
const s1 = Symbol("Disney");
const s2 = Symbol("Disney");
console.log(s1 == s2); // false
s1
is not equal to s2
, even though their Symbol description is same.
Symbols as object keys
In JavaScript, an object key should be either a string or a symbol. Other data types are not supported as object keys. Here is an example of an object literal.
const obj = {
name: "John Doe",
age: 23,
};
Now let us add a new Symbol key to obj
.
obj[Symbol("id")] = 1234;
We need to use square bracket
[]
syntax to add a Symbol key property to an object. Dot(.
) notation is not allowed to add Symbols to objects. Following code is invalid.obj.Symbol("id") = 1234;
What is the use of having a Symbol key?
Symbol keys in for..in
obj
object which we created above now have 3 keys(2 strings and 1 symbol). Now let us log the key names using for..in
loop.
for (key in obj) {
console.log(key);
}
And the output is
"name"
"age"
We cannot see Symbol("id")
in the list. Symbol keys act like private properties(in reality, they are not). They are not looped through when used with for..in
loop.
So, is this hiding behaviour applicable for all loops on objects?
Symbol keys with Object.keys()
The Object.keys()
method returns an array of a given object's own enumerable property names, in the same order as we get with a normal loop.
Let us try Object.keys()
on obj
object. Here is the full code from object creation to printing property names.
const obj = {
name: "John Doe",
age: 23,
};
obj[Symbol("id")] = 1234;
console.log(Object.keys(obj)); // ["name", "age"]
Here also the symbol keys are omitted. Only the string property names name
and age
are printed.
Symbols do not auto-convert to a string
In JavaScript, we can explicitly convert one data type to another using various techniques. One common conversion is converting a data type to string. All data types have .toString()
method which makes this job easy. Here are few examples.
console.log(true.toString()); // "true"
console.log(Number(123).toString()); // "123"
console.log([3, 5, 8].toString()); // "3,5,8"
In similar manner, we can convert a symbol to a string using .toString()
method.
const symbol1 = Symbol("Token");
console.log(symbol1.toString()); //"Symbol(Token)";
A symbol when converted to a string, outputs the Symbol()
function which created it, along with the symbol description(Token
).
There are cases where JavaScript implicitly convert a data type to string. Here are two examples.
console.log(1 + "2"); // "12"
alert([3, 4, 5]); // alerts "3,4,5"
What if we try to alert the value of a symbol? It throws an error. Let us try.
const symbol1 = Symbol("Token");
alert(symbol1); // TypeError: Cannot convert a Symbol value to a string
This says that, if we want to convert a symbol to string, we need to explicitly use .toString()
method. Otherwise, implicit conversion to string value results in TypeError.
Well-Known symbols
So far we learned how to create custom symbols. There are a set of built-in symbols in JavaScript called as Well-Known symbols. We can find these symbols as constants of Symbol
class. There are 13 such symbols.
Symbol.asyncIterator
Symbol.hasInstance
Symbol.isConcatSpreadable
Symbol.iterator
Symbol.match
Symbol.matchAll
Symbol.replace
Symbol.search
Symbol.species
Symbol.split
Symbol.toPrimitive
Symbol.toStringTag
Symbol.unscopables
We can find all these constant symbols, by going to browser console and type Symbol.
. Browser will show above symbols in the auto complete.
Well-known symbols are used by various algorithms(like for..of
loop) within JavaScript specification. To understand it better, let us take Symbol.iterator
. This symbol will be present as a key in any iterable object. Let us verify it.
An array in JavaScript is an iterable object. Whereas an object literal is not iterable.
// Iterable object
const arr = [2, 4, 6];
// Non iterable
const obj = {
name: "John",
age: 20,
};
Now let us see the value present in the Symbol.iterator
key.
console.log(arr[Symbol.iterator]); // function values() { [native code] }
console.log(obj[Symbol.iterator]); // undefined
Above statements show that, there is a Symbol.iterator
key in an array, but not present in an object. We can therefore test if an object is an iterable object by checking for Symbol.iterator
key.
Now let us go little more in depth. We now know, the Symbol.iterator
key inside arr
contains a function. If we execute that function, it returns an iterator object. Just for users who are new to iterators, an iterator object contains a next()
method which returns values one by one upon each invocation. Let us try it.
const arrayIteratorObject = arr[Symbol.iterator]();
console.log(arrayIteratorObject.next().value); // 2
console.log(arrayIteratorObject.next().value); // 4
console.log(arrayIteratorObject.next().value); // 6
console.log(arrayIteratorObject.next().value); // undefined
Object
An object is an unordered collection of properties, each of which has a name and value. In the following code, car
is an example of object in JavaScript.
const car = {
model: "GLS",
company: "Mercedes",
};
In the above object, model
and company
are properties of the object car
. Each properties can have a primitive value or another object value.
Empty Object
An object with no properties or methods inside it is an empty object.
const car = {};
Usage Scenario
Say, we are going to create a student
object. But all the properties of student
object is not available initially. In that case we start with an empty object at the start of program.
const student = {};
Then as the program progresses, we start assigning properties to student
object.
//...
student.name = `${firstName} ${lastName}`;
//...
student.marks = totalMarks;
Finally, we will get a student
object with two properties, name
and marks
.
Object Literal
As seen above, in JavaScript we can literally write an object by wrapping a set of key value pairs inside curly brackets {}
.
const car = {
model: "GLE",
company: "Mercedes",
};
In case of strings, we have string literals like "hello"
, "apple"
and so on. Object literals are something in similar lines for Objects.
Usage Scenario
In our application, we might need to store the configuration of something as an object literal. The key-value pair will be later used in our application.
const config = {
dbName: "library",
host: "localhost",
username: "johndoe",
password: "pass123",
};
Reading Object properties
As we already discussed, object is a collection of related information. We have an object here student
with some properties and method.
const student = {
name: "David",
course: "Computer Science",
subject1Mark: 92,
subject2Mark: 89,
subject3Mark: 91,
getAverageMark: function () {
return (this.subject1Mark + this.subject2Mark + this.subject3Mark) / 3;
},
};
Using Dot .
operator
We can use dot(.
) operator to read the value of an object key. We can read the value of name
property using .
operator.
console.log(student.name); // "David"
Using Bracket Notation []
We can also access object properties using []
notation.
console.log(student["name"]); // "David"
The syntax looks very similar to how we access elements of an array. That is the reason why objects can also be called as associative arrays.
Usage Scenario:
Sometimes objects have illegal identifier characters in the key.
const person = {
"full-name": "David Tom",
};
person
is a perfectly legal object. Now if we are trying to get the value of full-name
using .
operator, it will not work as expected.
console.log(person.full - name);
In this situation we need to use the bracket syntax.
console.log(person["full-name"]); // "David Tom"
Usage Scenario:
Sometimes the key to extract might reside inside a variable. In that case, we use bracket notation []
, to get the value. From the above student
object, if we are printing the marks in a loop, we can do like this.
for (let i = 1; i <= 3; i++) {
console.log(student[`subject${i}Mark`]);
}
Above code will output 92
, 89
, 91
in different lines. Here we used template literal string inside bracket notation.
Reading non-existent property
Say we have an object car
with two properties model
and year
.
const car = {
model: "Mercedes GLS",
year: 2019,
};
Now we are trying to get the value of a property color
which is not in car
object. Will it throw an error? No. Instead it will return undefined
.
console.log(car.color); // undefined
Setting Object Properties
We saw that we can read properties of an object either using dot(.
) operator or using bracket notation[]
. We can use the same operators to add / edit properties of an object. Here, we have an object car
.
const car = {
model: "Mercedes GLS",
year: 2019,
};
Adding new property
In JavaScript, we can dynamically create new properties or methods for an object. It can be done by just setting it. In car
object, there is no color
property. We can create it by just setting color
property.
car.color = "Black";
Now the car
object looks like:
{
model : "Mercedes GLS",
year : 2019,
color : "Black"
}
In the above code, we created a new property color
using dot(.
) notation. Instead, we can also create a new property using bracket notation[]
. Here is how it is done.
car["color"] = "Black";
Updating existing property
When we set a property of an object that does not exist, that property is created. If that property exists, then the value of that property is updated. In our car
object, the model
and year
property exists. The value of year
property is 2019
. Now we are going to set the value of year
property with a different year.
car.year = 2020;
Now the year
property is updated. Now the car
object looks like:
{
model : "Mercedes GLS",
year : 2020
}
As in the case of creating a new property, we can also update a property using bracket notation[]
.
car["year"] = 2020;
Note that when we used bracket notation,
year
is wrapped in quotes to form a string literal. If we use it without quotes, JavaScript engine will consider it as a variableyear
and will try to resolve it.
Using bracket notation[]
to handle dynamic keys
We can use variables inside bracket notation. This can come handy. We have a student
object here.
const student = {
name: "David",
age: 33,
};
What if the student "David"
have a unique property dreamingAbout
? How can we add that?
let dynamicProperty = "dreamingAbout";
let dynamicValue = "Riding Mercedes GLS AMG";
student[dynamicProperty] = dynamicValue;
See how we used variables to add a key value pair for an object. This can be achieved only using bracket notation[]
. Now the new property is ready to use.
console.log(student.dreamingAbout); // "Riding Mercedes GLS AMG"
Objects are mutable
Objects are mutable and are manipulated by reference rather than by value.
var x = {
name: "Apple",
color: "Red",
};
var y = x;
y.color = "Green";
console.log(x.color); // "Green"