kota's memex

creation

let day1 = {
	squirrel: false,
	events: ["work", "touched tree", "pizza", "running"]
};

properties

There are two main ways to access properties. With a dot value.x or brackets value[x]. The difference is in how x is interpreted. When using a dot, the work after the dot is the literal name of the property. When using brackets, the expression between the brackets is evaluated to get the property name. So if you know the property is named "color" you'd use value.color. If you wanted to extract the property named by the value held in variable x you would use value[x]. Property names are strings.

The elements in an array are stores as the array's properties, using numbers as the property names. Because you cannot use the dot notation with numbers and usually want to use a variable that holds the index anyway you must use bracket notation. The length property of an array tells how many elements it has. Typically, you'd write array.length, but array["length"] is technically valid.

keys

Object.keys returns an array of an objects properties.

check for a property

Objects can have hidden properties brought in from their prototype. For more information see js classes. The methods hasOwnProperty checks if an object has it's own property as opposed to inheriting it. The in operator can be used if you want to include inherited properties. Unfortunately, the hasOwnProperty method can be overwritten so it's best to use the following:

let map = {one: true, two: true, hasOwnProperty: true};

// Fix this call
console.log(map.hasOwnProperty("one"));

assign

A function that copies all properties from one object to another. Does not replace existing properties so you can use this to add a set of new properties to an object.

delete a property

One subtlety is that deleting an object is different than setting it's value to undefined. If the property exists, but is set to undefined, in will report true.

let anObj = {left: 1, right: 2};
console.log(anObj.left);
// 1
delete anObj.left;
console.log(anObj.left);
// undefined
console.log("left" in anObj.left);
// false
console.log("right" in anObj.left);
// true

methods

Methods are nothing more than properties that hold function values. When a function is called as a method; looked up as a property and immediately called, as in object.method() the variable this in it's body automatically points to the object that it was called on.

function speak(line) {
	console.log(`The ${this.type} rabbit says '${line}'`)
}
let whiteRabbit = {type: "white", speak}
let hungryRabbit = {type: "hungry", speak}

whiteRabbit.speak("Oh my ears and whiskers, " +
	"how late it's getting!")

hungryRabbit.speak("I could use a carrot right now.")

If you want to pass this explicitely (without needing to call the function from an object) you can use .call:
speak.call(hungryRabbit, "Burp!")

Arrow functions are different. They do not bind their own this but can see the this in the scope around them. So, you can reference the "outer" this inside a local arrow function.

prototypes

In addition to their own set of properties, most objects also have a prototype. A prototype is another object that is used as a fallback source of properties. Then an object gets a request for a property it does not have, it's prototype will be searched for the property, then the prototype's prototype, and so on.

let empty = {};
console.log(empty.toString)
// function toString(){ ... }
console.log(empty.toString())
// [object Object]

An empty object uses the Object.prototype which is the root prototype behind almost all objects. Functions derive from Function.prototype and arrays from Array.prototype. Those prototypes themselves have the prototype of Object.prototype:
console.log(Object.getPrototypeOf({}) == Object.prototype) // true

Additionally, you can create objects with a specific prototype. Using prototypes this way forms a rudimentary class system. Several newer language extensions exist make this a bit more ergonomic.