Tuesday 18 August 2020

Detecting a string in JavaScript

To detect whether a parameter is a primitive string, use typeof:
var aString = "my string";
var anInt = 5;
var anObj = {};
typeof aString === "string"; // true
typeof anInt === "string"; // false
typeof anObj === "string"; // false
If you ever have a String object, via new String("somestr"), then the above will not work. In this instance, we can
use instanceof:
var aStringObj = new String("my string");
aStringObj instanceof String; // true
To cover both instances, we can write a simple helper function:
var isString = function(value) {
 return typeof value === "string" || value instanceof String;
};
Add caption


var aString = "Primitive String";
var aStringObj = new String("String Object");
isString(aString); // true
isString(aStringObj); // true
isString({}); // false
isString(5); // false
Or we can make use of toString function of Object. This can be useful if we have to check for other types as well
say in a switch statement, as this method supports other datatypes as well just like typeof.
var pString = "Primitive String";
var oString = new String("Object Form of String");
Object.prototype.toString.call(pString);//"[object String]"
Object.prototype.toString.call(oString);//"[object String]" 
A more robust solution is to not detect a string at all, rather only check for what functionality is required. For
example:
var aString = "Primitive String";
// Generic check for a substring method
if(aString.substring) {
}
// Explicit check for the String substring prototype method
if(aString.substring === String.prototype.substring) {
 aString.substring(0, );
}

Escaping Quotes in JavaScript

If your string is enclosed (i.e.) in single quotes you need to escape the inner literal quote with backslash \
var text = 'L\'albero means tree in Italian';
console.log( text ); \\ "L'albero means tree in Italian"
Same goes for double quotes:
var text = "I feel \"high\"";
Special attention must be given to escaping quotes if you're storing HTML representations within a String, since
HTML strings make large use of quotations i.e. in attributes:

var content = "<p class=\"special\">Hello World!</p>"; // valid String
var hello = '<p class="special">I\'d like to say "Hi"</p>'; // valid String
Quotes in HTML strings can also be represented using &apos; (or &#39;) as a single quote and &quot; ( or &#34;) as
double quotes.
var hi = "<p class='special'>I'd like to say &quot;Hi&quot;</p>"; // valid String
var hello = '<p class="special">I&apos;d like to say "Hi"</p>'; // valid String
Note: The use of &apos; and &quot; will not overwrite double quotes that browsers can automatically place on
attribute quotes. For example <p class=special> being made to <p class="special">, using &quot; can lead to
<p class=""special""> where \" will be <p class="special">.
Version ≥ 6
If a string has ' and " you may want to consider using template literals (also known as template strings in previous ES6
editions), which do not require you to escape ' and ". These use backticks (`) instead of single or double quotes.
var x = `"Escaping " and ' can become very annoying`;

Reverse String in JavaScript

 The most "popular" way of reversing a string in JavaScript is the following code fragment, which is quite common:

function reverseString(str) {

 return str.split('').reverse().join('');

}

reverseString('string'); // "gnirts"

However, this will work only so long as the string being reversed does not contain surrogate pairs. Astral symbols,

Add caption


i.e. characters outside of the basic multilingual plane, may be represented by two code units, and will lead this

naive technique to produce wrong results. Moreover, characters with combining marks (e.g. diaeresis) will appear

on the logical "next" character instead of the original one it was combined with.

'?????.'.split('').reverse().join(''); //fails

While the method will work fine for most languages, a truly accurate, encoding respecting algorithm for string

reversal is slightly more involved. One such implementation is a tiny library called Esrever, which uses regular

expressions for matching combining marks and surrogate pairs in order to perform the reversing perfectly.

Explanation

Section Explanation Result

str The input string "string"

String.prototype.split(

deliminator )

Splits string str into an array. The

parameter "" means to split between each

character.

["s","t","r","i","n","g"]

Array.prototype.reverse()

Returns the array from the split string with

its elements in reverse order. ["g","n","i","r","t","s"]

Array.prototype.join( deliminator

)

Joins the elements in the array together into

a string. The "" parameter means an empty

deliminator (i.e., the elements of the array

are put right next to each other).


Basic Info and String Concatenation

Strings in JavaScript can be enclosed in Single quotes 'hello', Double quotes "Hello" and (from ES2015, ES6) in
Template Literals (backticks) `hello`.
var hello = "Hello";
var world = 'world';
var helloW = `Hello World`; // ES2015 / ES6
Strings can be created from other types using the String() function.
var intString = String(32); // "32"
var booleanString = String(true); // "true"
var nullString = String(null); // "null"
Or, toString() can be used to convert Numbers, Booleans or Objects to Strings.
var intString = (5232).toString(); // "5232"
var booleanString = (false).toString(); // "false"
Add caption

var objString = ({}).toString(); // "[object Object]"
Strings also can be created by using String.fromCharCode method.
String.fromCharCode(104,101,108,108,111) //"hello"
Creating a String object using new keyword is allowed, but is not recommended as it behaves like Objects unlike
primitive strings.
var objectString = new String("Yes, I am a String object");
typeof objectString;//"object"
typeof objectString.valueOf();//"string"
Concatenating Strings
String concatenation can be done with the + concatenation operator, or with the built-in concat() method on the
String object prototype.
var foo = "Foo";
var bar = "Bar";
console.log(foo + bar); // => "FooBar"
console.log(foo + " " + bar); // => "Foo Bar"
foo.concat(bar) // => "FooBar"
"a".concat("b", " ", "d") // => "ab d"
Strings can be concatenated with non-string variables but will type-convert the non-string variables into strings.
var string = "string";
var number = 32;
var boolean = true;
console.log(string + number + boolean); // "string32true"
Strings can be created using template literals (backticks) `hello`.
var greeting = `Hello`;
With template literals, you can do string interpolation using ${variable} inside template literals:
var place = `World`;
var greet = `Hello ${place}!`
console.log(greet); // "Hello World!"
You can use String.raw to get backslashes to be in the string without modification.
`a\\b` // = a\b
String.raw`a\\b` // = a\\b

Finding an object's class

 To find whether an object was constructed by a certain constructor or one inheriting from it, you can use the

instanceof command:

//We want this function to take the sum of the numbers passed to it

//It can be called as sum(1, 2, 3) or sum([1, 2, 3]) and should give 6

function sum(...arguments) {

 if (arguments.length === 1) {

 const [firstArg] = arguments

 if (firstArg instanceof Array) { //firstArg is something like [1, 2, 3]

 return sum(...firstArg) //calls sum(1, 2, 3)

 }

 }

 return arguments.reduce((a, b) => a + b)

}

console.log(sum(1, 2, 3)) //6

console.log(sum([1, 2, 3])) //6

console.log(sum(4)) //4

Note that primitive values are not considered instances of any class:

console.log(2 instanceof Number) //false

console.log('abc' instanceof String) //false

console.log(true instanceof Boolean) //false

console.log(Symbol() instanceof Symbol) //false

Every value in JavaScript besides null and undefined also has a constructor property storing the function that was

used to construct it. This even works with primitives.

//Whereas instanceof also catches instances of subclasses,

//using obj.constructor does not

console.log([] instanceof Object, [] instanceof Array) //true true

console.log([].constructor === Object, [].constructor === Array) //false true

function isNumber(value) {

 //null.constructor and undefined.constructor throw an error when accessed


 if (value === null || value === undefined) return false

 return value.constructor === Number

}

console.log(isNumber(null), isNumber(undefined)) //false false

console.log(isNumber('abc'), isNumber([]), isNumber(() => 1)) //false false false

console.log(isNumber(0), isNumber(Number('10.1')), isNumber(NaN)) //true true true

Formatting console output

 Many of the console's print methods can also handle C-like string formatting, using % tokens:

console.log('%s has %d points', 'Sam', 100);

Displays Sam has 100 points.

The full list of format specifiers in JavaScript is:

Specifier Output

%s Formats the value as a string

%i or %d Formats the value as an integer

%f Formats the value as a floating point value

%o Formats the value as an expandable DOM element

%O Formats the value as an expandable JavaScript object

%c Applies CSS style rules to the output string as specified by the second parameter

Advanced styling

When the CSS format specifier (%c) is placed at the left side of the string, the print method will accept a second

parameter with CSS rules which allow fine-grained control over the formatting of that string:

console.log('%cHello world!', 'color: blue; font-size: xx-large');


Displays:

It is possible to use multiple %c format specifiers:

any substring to the right of a %c has a corresponding parameter in the print method;

this parameter may be an empty string, if there is no need to apply CSS rules to that same substring;

if two %c format specifiers are found, the 1st (encased in %c) and 2nd substring will have their rules defined in

the 2nd and 3rd parameter of the print method respectively.

if three %c format specifiers are found, then the 1st, 2nd and 3rd substrings will have their rules defined in

the 2nd , 3rd and 4th parameter respectively, and so on...

console.log("%cHello %cWorld%c!!", // string to be printed

 "color: blue;", // applies color formatting to the 1st substring

 "font-size: xx-large;", // applies font formatting to the 2nd substring

 "/* no CSS rule*/" // does not apply any rule to the remaining substring

);

Output can be indented and enclosed in a collapsible group in the debugging console with the following methods:

console.groupCollapsed(): creates a collapsed group of entries that can be expanded through the

disclosure button in order to reveal all the entries performed after this method is invoked;

console.group(): creates an expanded group of entries that can be collapsed in order to hide the entries

after this method is invoked.

The indentation can be removed for posterior entries by using the following method:

console.groupEnd(): exits the current group, allowing newer entries to be printed in the parent group after

this method is invoked.

Groups can be cascaded to allow multiple indented output or collapsible layers within each other:

= Collapsed group expanded =>

Using HTML comments in JavaScript (Bad practice)

 HTML comments (optionally preceded by whitespace) will cause code (on the same line) to be ignored by the

browser also, though this is considered bad practice.

One-line comments with the HTML comment opening sequence (<!--):

Note: the JavaScript interpreter ignores the closing characters of HTML comments (-->) here.

<!-- A single-line comment.

<!-- --> Identical to using `//` since

<!-- --> the closing `-->` is ignored.

This technique can be observed in legacy code to hide JavaScript from browsers that didn't support it:

<script type="text/javascript" language="JavaScript">

<!--

/* Arbitrary JavaScript code.

 Old browsers would treat

 it as HTML code. */

// -->

</script>

An HTML closing comment can also be used in JavaScript (independent of an opening comment) at the beginning of

a line (optionally preceded by whitespace) in which case it too causes the rest of the line to be ignored:

--> Unreachable JS code

These facts have also been exploited to allow a page to call itself first as HTML and secondly as JavaScript. For

example:

<!--

self.postMessage('reached JS "file"');

/*

-->

<!DOCTYPE html>

<script>

var w1 = new Worker('#1');

w1.onmessage = function (e) {

 console.log(e.data); // 'reached JS "file"

};

</script>


<!--

*/

-->

When run a HTML, all the multiline text between the <!-- and --> comments are ignored, so the JavaScript

contained therein is ignored when run as HTML.

As JavaScript, however, while the lines beginning with <!-- and --> are ignored, their effect is not to escape over

multiple lines, so the lines following them (e.g., self.postMessage(...) will not be ignored when run as JavaScript,

at least until they reach a JavaScript comment, marked by /* and */. Such JavaScript comments are used in the

above example to ignore the remaining HTML text (until the --> which is also ignored as JavaScript).

Undefined and null

 At first glance it may appear that null and undefined are basically the same, however there are subtle but

important differences.

undefined is the absence of a value in the compiler, because where it should be a value, there hasn't been put one,

like the case of an unassigned variable.

undefined is a global value that represents the absence of an assigned value.

typeof undefined === 'undefined'

null is an object that indicates that a variable has been explicitly assigned "no value".

typeof null === 'object'

Setting a variable to undefined means the variable effectively does not exist. Some processes, such as JSON

serialization, may strip undefined properties from objects. In contrast, null properties indicate will be preserved so

you can explicitly convey the concept of an "empty" property.

The following evaluate to undefined:

A variable when it is declared but not assigned a value (i.e. defined)


let foo;

console.log('is undefined?', foo === undefined);

// is undefined? true

Accessing the value of a property that doesn't exist

let foo = { a: 'a' };

console.log('is undefined?', foo.b === undefined);

// is undefined? true

The return value of a function that doesn't return a value

function foo() { return; }

console.log('is undefined?', foo() === undefined);

// is undefined? true

The value of a function argument that is declared but has been omitted from the function call

function foo(param) {

 console.log('is undefined?', param === undefined);

}

foo('a');

foo();

// is undefined? false

// is undefined? true

undefined is also a property of the global window object.

// Only in browsers

console.log(window.undefined); // undefined

window.hasOwnProperty('undefined'); // true 

Version < 5

Before ECMAScript 5 you could actually change the value of the window.undefined property to any other value

potentially breaking everything.

NaN in JavaScript

 window.isNaN()

The global function isNaN() can be used to check if a certain value or expression evaluates to NaN. This function (in

short) first checks if the value is a number, if not tries to convert it (*), and then checks if the resulting value is NaN.

For this reason, this testing method may cause confusion.

(*) The "conversion" method is not that simple, see ECMA-262 18.2.3 for a detailed explanation of the algorithm.

These examples will help you better understand the isNaN() behavior:


isNaN(NaN); // true

isNaN(1); // false: 1 is a number

isNaN(-2e-4); // false: -2e-4 is a number (-0.0002) in scientific notation

isNaN(Infinity); // false: Infinity is a number

isNaN(true); // false: converted to 1, which is a number

isNaN(false); // false: converted to 0, which is a number

isNaN(null); // false: converted to 0, which is a number

isNaN(""); // false: converted to 0, which is a number

isNaN(" "); // false: converted to 0, which is a number

isNaN("45.3"); // false: string representing a number, converted to 45.3

isNaN("1.2e3"); // false: string representing a number, converted to 1.2e3

isNaN("Infinity"); // false: string representing a number, converted to Infinity

isNaN(new Date); // false: Date object, converted to milliseconds since epoch

isNaN("10$"); // true : conversion fails, the dollar sign is not a digit

isNaN("hello"); // true : conversion fails, no digits at all

isNaN(undefined); // true : converted to NaN

isNaN(); // true : converted to NaN (implicitly undefined)

isNaN(function(){}); // true : conversion fails

isNaN({}); // true : conversion fails

isNaN([1, 2]); // true : converted to "1, 2", which can't be converted to a number

This last one is a bit tricky: checking if an Array is NaN. To do this, the Number() constructor first converts the array

to a string, then to a number; this is the reason why isNaN([]) and isNaN([34]) both return false, but isNaN([1,

2]) and isNaN([true]) both return true: because they get converted to "", "34", "1,2" and "true" respectively. In

general, an array is considered NaN by isNaN() unless it only holds one element whose string representation

can be converted to a valid number.

Version ≥ 6

Number.isNaN()

In ECMAScript 6, the Number.isNaN() function has been implemented primarily to avoid the problem of

window.isNaN() of forcefully converting the parameter to a number. Number.isNaN(), indeed, doesn't try to

convert the value to a number before testing. This also means that only values of the type number, that are

also NaN, return true (which basically means only Number.isNaN(NaN)).

From ECMA-262 20.1.2.4:

When the Number.isNaN is called with one argument number, the following steps are taken:

1. If Type(number) is not Number, return false.

2. If number is NaN, return true.

3. Otherwise, return false.

Some examples:

// The one and only

Number.isNaN(NaN); // true

// Numbers

Number.isNaN(1); // false

Number.isNaN(-2e-4); // false

Number.isNaN(Infinity); // false

// Values not of type number

Number.isNaN(true); // false

Number.isNaN(false); // false

Number.isNaN(null); // false

Number.isNaN(""); // false

Number.isNaN(" "); // false

Number.isNaN("45.3"); // false

Number.isNaN("1.2e3"); // false

Number.isNaN("Infinity"); // false

Number.isNaN(new Date); // false

Number.isNaN("10$"); // false

Number.isNaN("hello"); // false

Number.isNaN(undefined); // false

Number.isNaN(); // false

Number.isNaN(function(){}); // false

Number.isNaN({}); // false

Number.isNaN([]); // false

Number.isNaN([1]); // false

Number.isNaN([1, 2]); // false

Number.isNaN([true]); // false

Array and Objects

var myArray = []; // empty array
An array is a set of variables. For example:
var favoriteFruits = ["apple", "orange", "strawberry"];
var carsInParkingLot = ["Toyota", "Ferrari", "Lexus"];
var employees = ["Billy", "Bob", "Joe"];
var primeNumbers = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31];
var randomVariables = [2, "any type works", undefined, null, true, 2.51];
myArray = ["zero", "one", "two"];
window.alert(myArray[0]); // 0 is the first element of an array
 // in this case, the value would be "zero"
myArray = ["John Doe", "Billy"];
elementNumber = 1;
window.alert(myArray[elementNumber]); // Billy
An object is a group of values; unlike arrays, we can do something better than them:
myObject = {};
john = {firstname: "John", lastname: "Doe", fullname: "John Doe"};
billy = {
 firstname: "Billy",
 lastname: undefined,
 fullname: "Billy"
};

Array

window.alert(john.fullname); // John Doe
window.alert(billy.firstname); // Billy
Rather than making an array ["John Doe", "Billy"] and calling myArray[0], we can just call john.fullname and
billy.fullname.