Skip to content

Instantly share code, notes, and snippets.

@ivan-kleshnin

ivan-kleshnin/oop.txt

Last active Jul 3, 2018
Embed
What would you like to do?
Object Oriented Programming
I Objects / Classes are main units of design
II Objects are namespaces (expression problem, duality with Functional Programming)
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
III Delegation / Inheritance (type dependency)
IV Constructors (vs data constructors)
V Mutability (shared state)
VI Fluent API (http://paqmind.com/blog/fluent-api-debunked/)
VII Instance
http://paqmind.com/blog/dialogue-with-oop-guy/
// === MANUAL DELEGATION ===
// I
let User = {
name: "",
role: "",
getName: function () {
return this.name
},
dataType: "user", // "constant" field
}
let Admin = {
name: "",
role: "admin",
prototype: User,
}
function makeUser({name, role}) {
return Object.assign(
{}, User, {name: name, role: role}
)
}
function makeAdmin({name}) {
return Object.assign(
{}, Admin, {name: name}
)
}
let user = makeUser({name: "Alice", role: "manager"})
let admin = makeAdmin({name: "Bob"})
// console.log(user.getName()) // Alice
// console.log(admin.getName()) // TypeError: admin.getName is not a function
// II
// function withDelegation(method, object) {
// if (object[method]) {
// return object[method].call(object)
// } else {
// throw Error("delegation is not implemented (yet)")
// }
// }
//
// console.log(withDelegation("getName", user)) // Alice
// console.log(withDelegation("getName", admin)) // Error: delegation is not implemented (yet)
// III
function get(propName, obj) {
if (propName in obj) {
return obj[propName]
} else if (obj.prototype) {
return get(propName, obj.prototype)
} else {
throw Error(`Cannot read property '${propName}' of ${obj}`)
}
}
function call(propName, object) {
let propValue = get(propName, object)
return propValue.call(object)
}
console.log(call("getName", user)) // Alice
console.log(call("getName", admin)) // Bob
console.log(get("dataType", user)) // user
console.log(get("dataType", admin)) // user
// === AUTO DELEGATION ===
// I
let User = {
name: "",
role: "",
getName: function () {
return this.name
},
dataType: "user", // "constant" field
}
let Admin = Object.assign(Object.create(User), {
name: "",
role: "admin",
prototype: User,
})
function makeUser({name, role}) {
return Object.assign(
Object.create(User), User, {name: name, role: role}
)
}
function makeAdmin({name}) {
return Object.assign(
Object.create(Admin), Admin, {name: name}
)
}
let user = makeUser({name: "Alice", role: "manager"})
let admin = makeAdmin({name: "Bob"})
console.log(user.getName()) // Alice
console.log(admin.getName()) // Bob
console.log(user.dataType) // user
console.log(admin.dataType) // user
// === AUTO INSTANTIATION ===
// I
function User({name, role}) {
this.name = name
this.role = role
return this
}
User.prototype.getName = function () {
return this.name
}
User.prototype.dataType = "user" // "constant" field
function Admin({name}) {
this.name = name
this.role = "admin"
}
Admin.prototype = Object.create(User.prototype)
let user = new User({name: "Alice", role: "manager"})
let admin = new Admin({name: "Bob"})
console.log(user.getName()) // Alice
console.log(admin.getName()) // Bob
console.log(user.dataType) // user
console.log(admin.dataType) // user
// === SYNTAX SUGAR ===
// I
class User {
constructor({name, role}) {
this.name = name
this.role = role
}
getName() {
return this.name
}
// static dataType = "user" // doesn't work (yet?!)
}
User.prototype.dataType = "user" // "constant" field
class Admin extends User {
constructor({name, role}) {
super({name: name, role: "admin"})
}
}
let user = new User({name: "Alice", role: "manager"})
let admin = new Admin({name: "Bob"})
console.log(user.getName()) // Alice
console.log(admin.getName()) // Bob
console.log(user.dataType) // user
console.log(admin.dataType) // user
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment