Javascripts collection objects types are custom objects, arrays, typed arrays, maps an sets all are which are used in other programming languages however Javascript has implemented with differences.
I have using objects in previous sections, now lets go a little deeper, as you already know object can store data and functions that can manipulate that data, you can create object in two ways using the new operator or using a object literal notation. Throughout the various sections you will see numerous examples using the Object type.
creating object using new | let person = new Object(); person.name = "Paul"; person.age = 21; |
creating object using object literal | let person = { name: "Paul", age: 21 5: true // you can also use numbers as property name }; ------------------------------------------------------------------------------------ let person = {}; // you can create a empty object and add it to later function test(person) { // remember objects are passed by reference person.name = "Paul"; person.age = 21; } |
accessing object | console.log(person["name"]); // "Paul" console.log(person.name); // "Paul" |
changing/adding property values | person["name"] = "Will" person.name = "Will" let personProperty = "name" person[personProperty] = "Will" // you can use a variable to change a property name person.createNewProperty = "Comedy" // add an additional property |
Arrays are used in nearly all programming languages, they are the most commonly used data store, they are simply to create and use and hence why they are popular. Arrays in Javascript are order and they can hold any types of data, and you can mix and match as well, they are not statical typed as in other programming languages, they are dynamic typed. Arrays will grow and shrink automatically as data is added or subtrcted from them, also arrays in Javascript start at 0, the first index is 0.
Creating arrays | let persons = new Array(); let persons = new Array("Paul", "Will", "Moore", "Graham"); let persons = new Array(20); // create array length of 20, could increase performance presetting array size |
Creating arrays using literal | let persons = []; let persons = ["Paul", "Will", "Moore", "Graham"]; let numbers = [1, 2, 3, 4, 5]; |
Creating arrays with holes | const options = [1,,,,5]; // false, true, true, true, false for (const option of options) { console.log(option === undefined); } console.log(options.length); // results in 5 |
Creating arrays using from() method | Array.from("Paul")); // ["P", "a", "u", "l"] ---------------------------------------------------------------- const m = new Map().set(1, 2).set(3, 4); const s = new Set().add(1).add(2).add(3).add(4); // Array.from() performs a shallow copy of an existing array let nums = Array.from(m); // [[1, 2], [3, 4]] let nums = Array.from(s); // [1, 2, 3, 4] Note: there are other ways to copy arrays |
Accessing arrays | let persons = ["Paul", "Will", "Moore", "Graham"]; console.log(persons[0]); // Paul console.log[persons.length - 1] // Graham |
Changing/adding array | let persons = ["Paul", "Will", "Moore", "Graham"]; persons[0] = "Arthur" // change an existing element persons[4] = "Norman" // add a new element in position 3 (remeber srats at 0) |
filling arrays | let binaryArray = [0, 0, 0, 0, 0]; binaryArray.fill(1); // fill array with 1's binaryArray.fill(0); // fill array with 0's (reset it) binaryArray.fill(1, 0, 2) // fill elements >= 0 and < 2 with 1's let ints = [0, 1, 2, 3, 4]; ints.copyWithin(5); // copy elements 0 to 5 to end of array alert(ints); // [0, 1, 2, 3, 4, 0, 1, 2, 3, 4] |
There are many other methods you can use with arrays like conversion, stack, queue, reordering, manipulating, iterative, search, reduction and location methods.
A Typed array refers to a colelction of specialized arrays that contain numeric types. The ArrayBuffer is a block of memory which is the fundamental unit referred to by all typed arrays and views. I am going to cover briefly cover each one.
Typed arrays are array-like objects that provide a mechanism for reading and writing raw binary data in memory buffers. JavaScript engines perform optimizations so that these arrays are fast. However, as web applications become more and more powerful, adding features such as audio and video manipulation, access to raw data using WebSockets, and so forth, it has become clear that there are times when it would be helpful for JavaScript code to be able to quickly and easily manipulate raw binary data.
ArrayBuffer | const buf1 = new ArrayBuffer(16); const buf2 = buf1.slice(4, 12); alert(buf2.byteLength); // 8 Note: a BufferArray cannot not be resized once created. |
You can can only access a BufferArray via a view, ther are a number of different views which I will cover now
Data views allows you to read/write to a BufferArray, it is design for file I/O and network I/O, this view is not iterable.
Data View | const buf = new ArrayBuffer(16); // DataView default to use the entire ArrayBuffer const fullDataView = new DataView(buf); fullDataView.byteOffset; // 0 fullDataView.byteLength; // 16 fullDataView.buffer === buf; // true // There are a number of element types that you can use, int8, Uint8, int16, Uint16, int32, Uint32, Float32, Float64 // Allocate two bytes of memory and declare a DataView const buf = new ArrayBuffer(2); const view = new DataView(buf); // Demonstrate that the entire buffer is indeed all zeroes // Check the first and second byte view.getInt8(0); // 0 view.getInt8(1); // 0 // Check the entire buffer view.getInt16(0); // 0 // Set the entire buffer to ones // 255 in binary is 11111111 (2^8 – 1) view.setUint8(0, 255); |
Typed Arrays is another form of a BufferArray view, this is different to data views but it enforces a single elementtype and obeys the system's native endianness and thus it has greater API and better performance.
Typed Array | // There are a number of element types that you can use, int8, Uint8, int16, Uint16, int32, Uint32, Float32, Float64 // Creates a Float32Array from arguments const floats = Float32Array.of(3.14, 2.718, 1.618); alert(floats.length); // 3 alert(floats.buffer.byteLength); // 12 alert(floats[2]); // 1.6180000305175781 |
Maps store data in key/value pairs, you could do this with Objects the differences are below:
There are two types of Maps, Map and WeakMap, the WeakMap is how the garbage collector treats its keys, if all references to the key are lost and there are no more references to the value it can be garbage collected. One problem with Map is the possibility of memory leak because the arrays ensure that references to each key and each value are maintained indefinitely, these references prevent the keys from being garbage collected, even if there are no other references to the object.
Weakmaps do not offer iteration and clear because key/value pairs can be destroyed at any time, you also have to have a reference to the key object. The idea with WeakMap is that it preserves the convention that values can only be retrieved with a reference to the key object.
Map examples | const m1 = new Map([ ["key1", "val1"], ["key2", "val2"], ["key3", "val3"] ]); ----------------------------------------------------------------------------------------------------- const persons = new Map(); persons.set("firstName", "Paul").set("lastName", "Valle"); persons.has("firstname"); // true persons.get("firstname"); // Paul persons.size // 3 ----------------------------------------------------------------------------------------------------- // Maps can use any data type - functions, symbols, objects, etc const m = new Map(); const functionKey = function() {}; const symbolKey = Symbol(); const objectKey = new Object(); m.set(functionKey, "functionValue"); m.set(symbolKey, "symbolValue"); m.set(objectKey, "objectValue"); m.get(functionKey); // functionValue m.get(symbolKey); // symbolValue m.get(objectKey); // objectValue Note: that Maps retain there order of insertion |
WeakMap examples | const wm = new WeakMap([ ["key1", "val1"], ["key2", "val2"], ["key3", "val3"] ]); ----------------------------------------------------------------------------------------------------- // Map and WeakMap use the same creation and methods. const persons = new WeakMap(); persons.set("firstName", "Paul").set("lastName", "Valle"); persons.has("firstname"); // true persons.get("firstname"); // Paul persons.size // 3 |
The set type in Javascript is very similar to arrays it offers you to store data that is unique, again we have a WeakSet type and works the same way WeakMap works regarding garbage collection.
Set example | // Sets maintain there order of insertion let s = new Set(); s.add("Paul"); s.add("Will"); s.add("Moore"); s.add("Graham"); s.add("Paul"); console.log(s) // Set { 'Paul', 'Will', 'Moore', 'Graham' }, notice only one Paul Note: set has methods add, delete, get, has, size,, clear, etc |
Iteration and Spread Operators
Iterators and the Spread operators (shallow copying) are useful when using on collection types, they allow for easy interoperability, cloning and modification of colelction types.
Iterator operator example | let iterableThings = [ Array.of(1, 2), typedArr = Int16Array.of(3, 4), new Map([[5, 6], [7, 8]]), new Set([9, 10]) ]; for (const iterableThing of iterableThings) { for (const x of iterableThing) { console.log(x); } } // results in 1, 2, 3, 4, [5, 6], [7, 8], 9, 10 |
Spread operator example | // Ideal for shallow copying let arr1 = [1, 2, 3]; let arr2 = [...arr1]; console.log(arr1); // [1, 2, 3] console.log(arr2); // [1, 2, 3] console.log(arr1 === arr2); // false |