148 lines
No EOL
5.9 KiB
JavaScript
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
|
|
}()); |