Stamp或者是一条出路
参考: js application的作者的作品, stamp, tape, 或许是一条出路.
用stamp的原因
- 原型代理, 就是上面工厂函数的原型构造方法.
- 实例状态, 可以封装每个实例自己的状态. 可以把属性直接传进去构造新对象. 构造之后也可以混入属性.
- 封装性, 函数式闭包, 形成私有属性.
作者原始的方案是构造函数有三个参数, 分别对应上面的内容.
- method, 对象的方法, 构造再原型上.
- state, 实例状态, 每个实例初始化.
- enclose, 私有属性和属性的提取方法. 构造在闭包.
现代的stamp方案有所不同
- 扩展的基础概念
- 有深度merge的概念了.
- 有static的概念, 这个等于类属性. 可以认为是全局属性.
- 有引用的概念了: conf.
- 有不可变frozen的概念, 只有一次赋值的机会, 赋值之后就不能改了: descriptor
- 通过 Property descriptors 实现.
- 私有变成了一个单独的模块
- 基础数据如下:
- 方法method
- 属性property
- 构造init, 这个比较特殊是一个固定名字的函数
- 合并/多重继承composer
init的示例是错的—已经提交修改, 并且修正了.
const { props, methods, init } = stampit;
const DefaultFoo = props({ foo: '能用function不能用=>' });
const PrintFoo = methods({ printFoo() { console.log(this.foo) } });
const PassFoo = init(function({ foo=this.foo }) { this.foo = foo });
const Foo = DefaultFoo.compose(PrintFoo, PassFoo)
const ff= Foo({foo: "xxxx"});
ff.printFoo(); // xxxx
const ff2= Foo();
ff2.printFoo(); // 能用function不能用=>
2019-05-23 后记
碰到了一个奇怪的问题, init的时候返回某个值(也就是说返回的不是默认的this)那么链式调用的methods中的方法不能被调用例如:
function teststampinit() {
const mckpoint = stampit()
.statics({
keymap: {},
})
.init(({ lng, lat, info, ...p }) => {
const t = {};
t.p = p;
t.lng = lng;
return t;
})
.methods({
info() {
//这个不能被调用.
return "ooo";
},
});
const xxx = mckpoint();
xxx.info(); //这里会提示info不是函数.
}
2019-05-25
设计模式:
- 所有的stamp都应该拥有从自身生成一个新的对象的能力. 写init的时候尤其要注意, 这样能避免很多if判断.
- 特别要注意的是自身生成时, 要记得赋值所有的属性.
- 函数尽量返回this, 除非read(0)这种特殊的读取类函数.
- init的默认值都要定义在参数上, 不要直接在属性里面赋值默认值, 因为这样会导致新建的对象和用作模板参数的对象的属性不一致.