In 2014 Douglas Crockford updated his advice not to use Object.create() and instead to do this with ES6:
https://youtu.be/PSGEjv3Tqo0?t=1506
function constructor(spec) {
let {member} = spec,
{other} = other_constructor(spec),
method = function () {
// member, other, method, spec
};
return Object.freeze({
method,
other
});
}
Here member
is one thing extracted from spec
, (you could extract more things too), other
is something extracted from another constructor, method
is something we've created ourselves, and Object.freeze()
returns a new object made up of all these parts, but one that can't be modified.
Example:
function thing(spec) {
let {name} = spec,
printName = function() {
console.log(`${name}\n`);
}
return Object.freeze({
name,
printName
});
}
function person(spec) {
let {name, printName} = thing(spec);
return Object.freeze({
name,
printName
});
}
const alice = person({name: 'Alice'});
const bob = person({name: 'Bob'});
alice.printName();
bob.printName();
Gives:
Alice
Bob
(You can try it in your browser console too if you like, refresh the page if you want to run the code a second time).
To deal with properties that you want to be able to change when you want other things fixed you can use getters and setters. Here's an example:
function point(spec) {
let {latitude, longitude} = spec;
return Object.freeze({
constant: "constant",
get latitude() { return latitude },
set latitude(value) { latitude = value },
get longitude() { return longitude },
set longitude(value) { longitude = value },
});
}
Here's how to use it:
const data = {latitude: 1, longitude: 2}
const p = point(data);
console.log(p.latitude);
p.latitude = -0.109
console.log(p.latitude);
console.log(JSON.stringify(p, null, 4));
console.log(data);
This all works as you'd expect, without the original data
object being changed:
1
-0.109
{
"constant": "constant",
"latitude": -0.109,
"longitude": 2
}
{ latitude: 1, longitude: 2 }
Because we used Object.freeze()
that the constant
key cannot be changed or deleted and new keys cannot be added. Any attempts are silently ignored.
This code:
p.constant = "changed";
delete p["constant"];
p["newkey"] = "value";
console.log(p);
console.log(JSON.stringify(p, null, 4));
Gives the same data as before:
{ constant: 'constant',
latitude: [Getter/Setter],
longitude: [Getter/Setter] }
{
"constant": "constant",
"latitude": -0.109,
"longitude": 2
}
Tip: If you don't want the errors silently ignored you can run the code in strict mode. For Node that means adding "use strict";
to the top of the file or running with node --use_strict
.
Copyright James Gardner 1996-2020 All Rights Reserved. Admin.