Skip to content

Commit

Permalink
feat: class inherit method
Browse files Browse the repository at this point in the history
  • Loading branch information
bubkoo committed Mar 18, 2020
1 parent b61a25a commit 662da0e
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 15 deletions.
83 changes: 83 additions & 0 deletions packages/x6/src/util/object/inherit.ts
@@ -0,0 +1,83 @@
/**
* @see https://www.typescriptlang.org/docs/handbook/mixins.html
*/
export function applyMixins(derivedCtor: any, ...baseCtors: any[]) {
baseCtors.forEach(baseCtor => {
Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {
Object.defineProperty(
derivedCtor.prototype,
name,
Object.getOwnPropertyDescriptor(baseCtor.prototype, name)!,
)
})
})
}

const extendStatics =
Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array &&
function(d, b) {
d.__proto__ = b
}) ||
function(d, b) {
for (const p in b) {
if (b.hasOwnProperty(p)) {
d[p] = (b as any)[p]
}
}
}

/**
* @see https://github.com/microsoft/TypeScript/blob/5c85febb0ce9d6088cbe9b09cb42f73f9ee8ea05/src/compiler/transformers/es2015.ts#L4309
*/
export function inherit(cls: Function, base: Function) {
extendStatics(cls, base)
function tmp() {
this.constructor = cls
}
cls.prototype =
base === null
? Object.create(base)
: ((tmp.prototype = base.prototype), new (tmp as any)())
}

let seed = 0
const classIdMap = new WeakMap<Function, string>()
function getClassId(c: Function) {
let id = classIdMap.get(c)
if (id == null) {
id = `c${seed}`
seed += 1
classIdMap.set(c, id)
}
return id
}

function cacheClass(c: Function) {
const win = window as any
const key = '__x6_class__'
let cache = win[key]
if (cache == null) {
cache = win[key] = {}
}

const id = getClassId(c)
if (cache[id] == null) {
cache[id] = c
}

return `window['${key}']['${id}']`
}

/**
* Extends class with specified class name.
*/
export function createClass<T>(className: string, base: Function): T {
const fn = cacheClass(base)
// tslint:disable-next-line
const cls = new Function(
`return function ${className}() { return ${fn}.apply(this, arguments) }`,
)()
inherit(cls, base)
return cls as T
}
17 changes: 2 additions & 15 deletions packages/x6/src/util/object/object.ts
Expand Up @@ -12,22 +12,9 @@ export {
extend,
} from 'lodash'

import { has, isPlainObject } from 'lodash'
export * from './inherit'

/**
* @see https://www.typescriptlang.org/docs/handbook/mixins.html
*/
export function applyMixins(derivedCtor: any, ...baseCtors: any[]) {
baseCtors.forEach(baseCtor => {
Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {
Object.defineProperty(
derivedCtor.prototype,
name,
Object.getOwnPropertyDescriptor(baseCtor.prototype, name)!,
)
})
})
}
import { has, isPlainObject } from 'lodash'

export function ensure<T>(value: T | null | undefined, defaultValue: T) {
return value != null ? value : defaultValue!
Expand Down

0 comments on commit 662da0e

Please sign in to comment.