alert(Array.isArray({})); // false
alert(Array.isArray([])); // true
let fruits = []; // make an array
fruits[99999] = 5; // assign a property with the index far greater than its length
fruits.age = 25; // create a property with an arbitrary name
let fruits = ["Apple", "Orange", "Plum"];
fruits[2] = 'Pear'; // now ["Apple", "Orange", "Pear"]

for (let i = 0; i < arr.length; i++) {
  alert( arr[i] );
}

for (let fruit of fruits) {
  alert( fruit );
}

// An array can store elements of any type.
let arr = [
	'Apple', 
	{ name: 'John' },
	true, 
	function() { 
		alert('hello'); 
	}
];
arr[3](); // hello

// Although for..in is possible, it is considered as a bad idea:
// It iterates over all properties not just array elements.
// The for..in loop is optimized for generic objects, not arrays and thus is 10-100 times slower.

push, pop, shift, unshift

const fruits = ["Apple", "Orange", "Pear"];
const pear = fruits.pop(); // remove "Pear"
// fruits: Apple, Orange

fruits.push("Pear"); // The call fruits.push(...) is equal to fruits[fruits.length] = ...
// fruits: Apple, Orange, Pear

// shift Extracts the first element of the array and returns it:
const firstElement = fruits.shift(); // remove Apple and alert it

// unshift Add the element to the beginning of the array:
fruits.unshift('Apple');
// fruits: Apple, Orange, Pear

// Methods push and unshift can add multiple elements at once.
fruits.push("Orange", "Peach");
fruits.unshift("Pineapple", "Lemon");

array.forEach()

let myList = ["Bilbo", "Gandalf", "Nazgul"];

myList.forEach((item, index, array) => {
  console.log(`${item} is at index ${index} in ${array}`);
});

myList.forEach(alert);

indexOf, lastIndexOf & includes

let arr = [1, 0, false];

alert(arr.indexOf(0)); // 1
alert(arr.indexOf(false)); // 2
alert(arr.indexOf(null)); // -1

alert(arr.includes(1)); // true
const arr = [NaN];
alert( arr.indexOf(NaN) ); // -1 (should be 0, but === equality doesn't work for NaN)
alert( arr.includes(NaN) );// true (correct)

find and findIndex