-
Notifications
You must be signed in to change notification settings - Fork 2
/
extendables.js
64 lines (55 loc) · 2.1 KB
/
extendables.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
/* vim:set ts=2 sw=2 sts=2 expandtab */
/*jshint undef: true es5: true node: true devel: true
forin: true latedef: false supernew: true */
/*global define: true */
(typeof define !== "function" ? function($){ $(require, exports, module); } : define)(function(require, exports, module, undefined) {
"use strict";
function getOwnPropertyDescriptors(object) {
var descriptors = {};
Object.getOwnPropertyNames(object).forEach(function(name) {
descriptors[name] = Object.getOwnPropertyDescriptor(object, name);
});
return descriptors;
}
function supplement(target, source) {
var descriptors = {};
var names = Object.getOwnPropertyNames(target);
Object.getOwnPropertyNames(source).forEach(function(name) {
if (!~names.indexOf(name)) {
descriptors[name] = Object.getOwnPropertyDescriptor(source, name);
}
});
return Object.defineProperties(target, descriptors);
}
function Constructor(base) {
return function Extendable() {
var value, extendable = this;
if (!(extendable instanceof Extendable))
extendable = Object.create(Extendable.prototype);
value = base.apply(extendable, arguments);
return value === undefined ? extendable : value;
};
}
function Extendable() {
return this instanceof Extendable ? this : Object.create(Extendable.prototype);
}
Object.defineProperties(Extendable, {
extend: {
value: function extend(source) {
var constructor, descriptors = getOwnPropertyDescriptors(source || {});
// If `constructor` is not defined by `source` then we generate a default
// `constructor` that delegates to the `constructor` of the base class.
if (typeof descriptors.constructor !== "object")
descriptors.constructor = { value: new Constructor(this) };
// Copying all the non-existing properties to the decedent.
constructor = supplement(descriptors.constructor.value, this);
// Override prototype of the decedent.
constructor.prototype = Object.create(this.prototype, descriptors);
return constructor;
},
enumerable: true
}
});
exports.Extendable = Extendable;
exports.version = "0.1.2";
});