不要在类构造器内实例化当前对象也就是说不要将类class
当做function
使用
请抛弃旧有的编码习惯:
function Element (tagName, props, children) {
if (!(this instanceof Element)) {
if (!_.isArray(children) && children != null) {
children = _.slice(arguments, 2).filter(_.truthy)
}
return new Element(tagName, props, children)
}
// ......
}
我们在TS
或ES6
编码时会习惯性沿用ES5
时代的编码习惯
export class Element implements IVNode {
// ....
constructor(_tagName: string);
constructor(_tagName: string, children: any);
constructor(_tagName: string, props: T_OBJ);
constructor(_tagName: string, props: T_OBJ, children: T_ArrayNode);
constructor(_tagName: string, props?: T_OBJ, children?: T_ArrayNode) {
if (!(this instanceof Element)) {
if (typeof props !== "undefined") {
if (Array.isArray(children)) {
return new Element(_tagName, props, children);
} else {
return new Element(_tagName, props);
}
} else {
if (Array.isArray(children)) {
return new Element(_tagName, children);
}
}
return new Element(_tagName);
}
// ....
这种编码方式导致class
, function
定义不明确,职责不清晰,我们是不提倡的
推荐将实例化的代码抽离
export class Element implements IVNode {
constructor(_tagName: string, props?: T_OBJ, children?: T_ArrayNode) {
// ...
}
}
export default function (_tagName: string): IVNode
export default function (_tagName: string, children: T_ArrayNode): IVNode
export default function (_tagName: string, props: T_OBJ): IVNode
export default function (_tagName: string, props: T_OBJ, children: T_ArrayNode): IVNode
export default function (_tagName: string, props?: T_OBJ, children?: T_ArrayNode): IVNode {
if (arguments.length === 2) {
const tmp = arguments[1]
if (Array.isArray(tmp)) {
return new Element(_tagName, {}, tmp)
} else {
return new Element(_tagName, tmp, [])
}
} else if (arguments.length === 1) {
return new Element(_tagName, {}, [])
}
return new Element(_tagName, props, children)
}