javascript_the_good_parts_n.../_3_objects.js
2020-11-05 16:19:36 +01:00

148 lines
No EOL
5.9 KiB
JavaScript

(function () {
console.info("**Chapter 3 Objects**\n");
/*
* letter: [A-Za-z]
* digit: [0-9]
* underscore: _
* name: [letter][letter digit underscore]*
*
*/
let empty_object = {};
// object literals
console.info("*Object Literals*\n");
let stooge = {
"first-name": "Jerome", // object property name must be quoted, because it is not a legal javascript _name_
"last-name": "Howard"
};
console.info(`let stooge = {
"first-name": "Jerome", // object property name must be quoted, because it is not a legal javascript name
"last-name": "Howard"
};`);
console.info("Retrieve property with 'stooge[\"first-name\"]': ", stooge["first-name"]);
// nested object
let flight = {
airline: "Oceanic",
number: 815,
departure: {
IATA: "SYD",
time: "2004-09-22 14:55",
city: "Sydney"
},
arrival: "LAX",
time: "2004-09-23 10:42",
city: "Los Angeles"
};
console.info(`\nlet flight = {
airline: "Oceanic",
number: 815,
departure: {
IATA: "SYD",
time: "2004-09-22 14:55",
city: "Sydney"
},
arrival: "LAX",
time: "2004-09-23 10:42",
city: "Los Angeles"
};`);
console.info("Retrieve property with 'flight.departure.IATA': ", flight.departure.IATA);
console.info("Retrieve undefined property with 'flight.status': ", flight.status);
try {
console.info("Retrieve property of undefined with 'flight.equipment.model': ");
console.info(flight.equipment.model);
} catch (e) {
console.info("\tCaught error:", e.message);
}
console.info(`Retrieve property of undefined with 'flight.equipment && flight.equipment.model': ${flight.equipment && flight.equipment.model}`);
// update
stooge["first-name"] = "Moe";
console.info(`Retrieve updated property with 'stooge["first-name"]': ${stooge["first-name"]}`);
stooge["middle-name"] = "middle-stooge";
console.info(`Retrieve property of augmented object with 'stooge["middle-name"]': ${stooge["middle-name"]}`);
let x = stooge;
x.nickname = "Curly";
let nick = stooge.nickname;
console.info(`nick is 'Curly' because x and stooge are references to the same object: ${nick}`);
// Prototype
console.info("\n*Prototype*\n");
//create a new object from a prototype
if (typeof Object.createFrom !== "function") { // 'create' is a built-in starting from ES5
Object.createFrom = function (o) {
let F = function () {
};
F.prototype = o;
return new F();
};
}
console.info(`Object.createFrom = ${Object.createFrom}`);
let another_stooge = Object.createFrom(stooge);
another_stooge["first-name"] = "Shemp";
console.info(`another stooge is created from stooge, but is a new reference. another_stooge.first-name = ${another_stooge["first-name"]}`);
console.info(`stooge is unchanged stooge.first-name = ${stooge["first-name"]}`);
// reflection
console.info("\n*Reflection*");
console.info("\nThe type of a property is retrieved wth 'typeof property'");
console.info(`typeof flight.number = ${typeof flight.number}`,);
console.info(`typeof flight.status = ${typeof flight.status}`);
console.info(`typeof flight.arrival = ${typeof flight.arrival}`);
console.info(`typeof flight.manifest = ${typeof flight.manifest}`);
console.info(`typeof flight.toString = ${typeof flight.toString}`);
console.info("\nhasOwnProperty returns true if the object defines that property");
console.info(`flight.hasOwnProperty("number"): ${Object.prototype.hasOwnProperty.call(flight, "number")}`); // the actual code is actually correct
console.info(`flight.hasOwnProperty("constructor"): ${Object.prototype.hasOwnProperty.call(flight, "constructor")}`);
// enumeration
console.info("\n*Enumeration*");
console.info("Enumeration shows all properties of an object");
// order is not guaranteed
console.info(`for (let name in another_stooge) {
if (typeof another_stooge[name] !== 'function') { // intellij warns that hasOwnProperty check is *probably* missing but that would change the output, because most properties are in the prototype!
console.info(\`name: \${another_stooge[name]}\`)
}
}`);
for (let name in another_stooge) {
if (typeof another_stooge[name] !== "function") { // intellij warns that hasOwnProperty check is *probably* missing but that would change the output, because most properties are in the prototype!
console.info(`name: ${another_stooge[name]}`);
}
}
// order is guaranteed
console.info("\nAgain with fixed properties in guaranteed order:");
console.info(`const properties = ['first-name', 'middle-name', 'last-name', 'profession'];
for (let i = 0; i < properties.length; i++) {
console.log(\`\${properties[i]}: \${another_stooge[properties[i]]}\`);
}`);
const properties = ["first-name", "middle-name", "last-name", "profession"];
for (let i = 0; i < properties.length; i++) {
console.log(`${properties[i]}: ${another_stooge[properties[i]]}`);
}
//delete
console.info("\n*Delete*");
console.info("_delete_ deletes a property, and this has the effect that it's prototype property of the same name (if it's there) is now visible");
another_stooge.nickname = "Moe";
console.info(`=> original nickname: ${another_stooge.nickname}`);
console.info("Delete reveals prototype value");
console.info("delete another_stooge.nickname;");
delete another_stooge.nickname;
console.info(`=> nickname after delete: ${another_stooge.nickname}`);
delete stooge.nickname;
console.info("delete another_stooge.nickname;");
console.info(`=> nickname after delete stooge.nickname: ${another_stooge.nickname}`);
// Global atonement
// no examples
}());