Data types Flashcards
Which is heavier- objecs or primitives ?
Objects are “heavier” than primitives. They require additional resources to support the internal machinery.
Are functions in JS objects ?
Yes
Are primitives like string, number objects ? because we can use methods like str.toUpperCase() ?
Primitives are not objects
let str = “Hello”;
alert( str.toUpperCase() ); // HELLO
As we know primitives are not objects still we are able to call toUpperCase() on str. How this code works ?
Simple, right? Here’s what actually happens in str.toUpperCase():
The string str is a primitive. So in the moment of accessing its property, a special object is created that knows the value of the string, and has useful methods, like toUpperCase().
That method runs and returns a new string (shown by alert).
The special object is destroyed, leaving the primitive str alone.
So primitives can provide methods, but they still remain lightweight.
The JavaScript engine highly optimizes this process. It may even skip the creation of the extra object at all. But it must still adhere to the specification and behave as if it creates one.
Consider the following code:
let str = “Hello”;
str.test = 5;
alert(str.test);
How do you think, will it work? What will be shown?
let str = “Hello”;
str.test = 5; // (*)
alert(str.test);
Depending on whether you have use strict or not, the result may be:
undefined (no strict mode) An error (strict mode). Why? Let’s replay what’s happening at line (*):
When a property of str is accessed, a “wrapper object” is created.
In strict mode, writing into it is an error.
Otherwise, the operation with the property is carried on, the object gets the test property, but after that the “wrapper object” disappears, so in the last line str has no trace of the property.
This example clearly shows that primitives are not objects.
They can’t store additional data.
Do null/undefined also have some methods that we can call ?
The special primitives null and undefined are exceptions. They have no corresponding “wrapper objects” and provide no methods. In a sense, they are “the most primitive”.
An attempt to access a property of such value would give the error:
alert(null.test); // error
What are the two types of numbers in JS ?
In modern JavaScript, there are two types of numbers:
Regular numbers in JavaScript are stored in 64-bit format IEEE-754, also known as “double precision floating point numbers”. These are numbers that we’re using most of the time, and we’ll talk about them in this chapter.
BigInt numbers, to represent integers of arbitrary length. They are sometimes needed, because a regular number can’t safely exceed 2^53 or be less than -2^53. As bigints are used in few special areas, we devote them a special chapter BigInt.
What are the two ways of writing 1 billion ?
let billion = 1000000000; We also can use underscore _ as the separator:
let billion = 1_000_000_000;
Here the underscore _ plays the role of the “syntactic sugar”, it makes the number more readable. The JavaScript engine simply ignores _ between digits, so it’s exactly the same one billion as above.
In real life though, we try to avoid writing long sequences of zeroes. We’re too lazy for that. We’ll try to write something like “1bn” for a billion or “7.3bn” for 7 billion 300 million. The same is true for most large numbers.
How to use ‘e’ for writing large numbers ?
let billion = 1e9; // 1 billion, literally: 1 and 9 zeroes
alert( 7.3e9 ); // 7.3 billions (same as 7300000000 or 7_300_000_000)
In other words, e multiplies the number by 1 with the given zeroes count.
1e3 === 1 * 1000; // e3 means *1000
1.23e6 === 1.23 * 1000000; // e6 means *1000000
How to write very small numbers in JS ?
Now let’s write something very small. Say, 1 microsecond (one millionth of a second):
let mсs = 0.000001;
Just like before, using “e” can help. If we’d like to avoid writing the zeroes explicitly, we could write the same as:
let mcs = 1e-6; // six zeroes to the left from 1 If we count the zeroes in 0.000001, there are 6 of them. So naturally it’s 1e-6.
In other words, a negative number after “e” means a division by 1 with the given number of zeroes:
// -3 divides by 1 with 3 zeroes 1e-3 === 1 / 1000; // 0.001
// -6 divides by 1 with 6 zeroes 1.23e-6 === 1.23 / 1000000; // 0.00000123
How to write Hex, binary and octal numbers in JS ?
Hexadecimal numbers are widely used in JavaScript to represent colors, encode characters, and for many other things. So naturally, there exists a shorter way to write them: 0x and then the number.
For instance:
alert( 0xff ); // 255
alert( 0xFF ); // 255 (the same, case doesn’t matter)
Binary and octal numeral systems are rarely used, but also supported using the 0b and 0o prefixes:
let a = 0b11111111; // binary form of 255 let b = 0o377; // octal form of 255
alert( a == b ); // true, the same number 255 at both sides
There are only 3 numeral systems with such support. For other numeral systems, we should use the function parseInt (which we will see later in this chapter).
How does toString(base) works ?
The method num.toString(base) returns a string representation of num in the numeral system with the given base.
For example:
let num = 255;
alert( num.toString(16) ); // ff
alert( num.toString(2) ); // 11111111
The base can vary from 2 to 36. By default it’s 10.
Common use cases for this are:
base=16 is used for hex colors, character encodings etc, digits can be 0..9 or A..F.
base=2 is mostly for debugging bitwise operations, digits can be 0 or 1.
base=36 is the maximum, digits can be 0..9 or A..Z. The whole latin alphabet is used to represent a number. A funny, but useful case for 36 is when we need to turn a long numeric identifier into something shorter, for example to make a short url. Can simply represent it in the numeral system with base 36:
alert( 123456..toString(36) ); // 2n9c
Please note that two dots in 123456..toString(36) is not a typo. If we want to call a method directly on a number, like toString in the example above, then we need to place two dots .. after it.
If we placed a single dot: 123456.toString(36), then there would be an error, because JavaScript syntax implies the decimal part after the first dot. And if we place one more dot, then JavaScript knows that the decimal part is empty and now goes the method.
Also could write (123456).toString(36).
Round
How we do rounding in JS. List four methods of doing so as - Math.floor, Math.ciel, Math.round, Math.trunc ?
How to round the digits to nth place after decimal ?
The method toFixed(n) rounds the number to n digits after the point and returns a string representation of the result.
let num = 12.34; alert( num.toFixed(1) ); // "12.3" This rounds up or down to the nearest value, similar to Math.round:
let num = 12.36; alert( num.toFixed(1) ); // "12.4"
Advantages of backticks ?
allow us to embed any expression into the string, by wrapping it in ${…}:
function sum(a, b) { return a + b; }
alert(1 + 2 = ${sum(1, 2)}.
); // 1 + 2 = 3.
Another advantage of using backticks is that they allow a string to span multiple lines:
let guestList = `Guests: * John * Pete * Mary `;
alert(guestList); // a list of guests, multiple lines
Are strings immutable in JS ?
Yes
How to change the case of strings ?
Methods toLowerCase() and toUpperCase() change the case:
alert( ‘Interface’.toUpperCase() ); // INTERFACE
alert( ‘Interface’.toLowerCase() ); // interface
Or, if we want a single character lowercased:
alert( ‘Interface’[0].toLowerCase() ); // ‘i’
How the str.indexOf() works ?
The first method is str.indexOf(substr, pos).
It looks for the substr in str, starting from the given position pos, and returns the position where the match was found or -1 if nothing can be found.
For instance:
let str = ‘Widget with id’;
alert( str.indexOf(‘Widget’) ); // 0, because ‘Widget’ is found at the beginning
alert( str.indexOf(‘widget’) ); // -1, not found, the search is case-sensitive
alert( str.indexOf(“id”) ); // 1, “id” is found at the position 1 (..idget with id)
The optional second parameter allows us to start searching from a given position.
For instance, the first occurrence of “id” is at position 1. To look for the next occurrence, let’s start the search from position 2:
let str = ‘Widget with id’;
alert( str.indexOf(‘id’, 2) ) // 12
How the includes() works ?
The more modern method str.includes(substr, pos) returns true/false depending on whether str contains substr within.
It’s the right choice if we need to test for the match, but don’t need its position:
alert( “Widget with id”.includes(“Widget”) ); // true
alert( “Hello”.includes(“Bye”) ); // false
The optional second argument of str.includes is the position to start searching from:
alert( “Widget”.includes(“id”) ); // true
alert( “Widget”.includes(“id”, 3) ); // false, from position 3 there is no “id”
How startsWith() and endWith() works ?
The methods str.startsWith and str.endsWith do exactly what they say:
alert( “Widget”.startsWith(“Wid”) ); // true, “Widget” starts with “Wid”
alert( “Widget”.endsWith(“get”) ); // true, “Widget” ends with “get”
let str = “stringify”;
alert( str.slice(0, 5) );
alert( str.slice(0, 1) );
How it works ?
let str = “stringify”;
alert( str.slice(0, 5) ); // ‘strin’, the substring from 0 to 5 (not including 5)
alert( str.slice(0, 1) ); // ‘s’, from 0 to 1, but not including 1, so only character at 0
If there is n
str.slice(start [, end])
Returns the part of the string from start to (but not including) end.
F
let str = "stringify"; alert( str.slice(2) ); // Output ?
let str = “stringify”;
alert( str.slice(2) ); // ‘ringify’, from the 2nd position till the end
If there is no second argument, then slice goes till the end of the string:
let str = “stringify”;
alert( str.slice(-4, -1) ); // Output ?
Negative values for start/end are also possible. They mean the position is counted from the string end:
let str = “stringify”;
// start at the 4th position from the right, end at the 1st from the right alert( str.slice(-4, -1) ); // 'gif'
let str = “stringify”;
alert( str.substring(2, 6) );
alert( str.substring(6, 2) );
alert( str.slice(2, 6) );
alert( str.slice(6, 2) );
str.substring(start [, end])
Returns the part of the string between start and end.
This is almost the same as slice, but it allows start to be greater than end.
For instance:
let str = “stringify”;
// these are same for substring
alert( str.substring(2, 6) ); // “ring”
alert( str.substring(6, 2) ); // “ring”
// …but not for slice:
alert( str.slice(2, 6) ); // “ring” (the same)
alert( str.slice(6, 2) ); // “” (an empty string)
Negative arguments are (unlike slice) not supported, they are treated as 0.