- Регистрация
- 1 Мар 2015
- Сообщения
- 1,481
- Баллы
- 155
An example of Class Free Object Oriented (CFOO) JS-code.
The last years my JS contains almost exclusively (actually the revealing module pattern). It's a very elegant and relative simple and robust way to create 'constructors' without the need for this or class syntax (aka class sugar). I'd like to share the idea here.
Constructors are created using factory functions, which return frozen objects. Factory functions may include ('inherit') other factory instances. Variable privacy is guaranteed via closures.
The basic pattern is (note: variables/types are not checked here)
const helloWorld = myConstructorFactory(myOtherConstructorFactory());
const universe = helloWorld("universe");
console.log(String(universe));
// 'hello world'
console.log(String(universe.setWorld("universe")));
// 'hello universe'
console.log(String(universe.setHello("Hi")));
// 'Hi universe'
console.log(universe.name);
// 'universe'
universe.name = "nothing";
// TypeError: Cannot set property name of [object Object]
// which has only a getter
universe.instanceName = "nothing";
// TypeError: Cannot add property instanceName, object is not extensible
function myConstructorFactory(inherits) {
let {hello, world} = inherits;
return function(instanceName) {
const instance = {
get name() { return instanceName; },
toString() {return hello + " " + world; },
setWorld(value) { world = value; return instance; },
setHello(value) { hello = value; return instance; }
};
return Object.freeze(instance);
}
}
function myOtherConstructorFactory(hi, wrld) {
return Object.freeze( {
hello: hi || "hello",
world: wrld || "world" } );
}
A more extensive example:
I created a simple, but more complete example @ stackblitz. Feel free to tinker with it.
The last years my JS contains almost exclusively (actually the revealing module pattern). It's a very elegant and relative simple and robust way to create 'constructors' without the need for this or class syntax (aka class sugar). I'd like to share the idea here.
Constructors are created using factory functions, which return frozen objects. Factory functions may include ('inherit') other factory instances. Variable privacy is guaranteed via closures.
The basic pattern is (note: variables/types are not checked here)
const helloWorld = myConstructorFactory(myOtherConstructorFactory());
const universe = helloWorld("universe");
console.log(String(universe));
// 'hello world'
console.log(String(universe.setWorld("universe")));
// 'hello universe'
console.log(String(universe.setHello("Hi")));
// 'Hi universe'
console.log(universe.name);
// 'universe'
universe.name = "nothing";
// TypeError: Cannot set property name of [object Object]
// which has only a getter
universe.instanceName = "nothing";
// TypeError: Cannot add property instanceName, object is not extensible
function myConstructorFactory(inherits) {
let {hello, world} = inherits;
return function(instanceName) {
const instance = {
get name() { return instanceName; },
toString() {return hello + " " + world; },
setWorld(value) { world = value; return instance; },
setHello(value) { hello = value; return instance; }
};
return Object.freeze(instance);
}
}
function myOtherConstructorFactory(hi, wrld) {
return Object.freeze( {
hello: hi || "hello",
world: wrld || "world" } );
}
A more extensive example:
I created a simple, but more complete example @ stackblitz. Feel free to tinker with it.