You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
90 lines
2.2 KiB
90 lines
2.2 KiB
/*! |
|
* static-extend <https://github.com/jonschlinkert/static-extend> |
|
* |
|
* Copyright (c) 2016, Jon Schlinkert. |
|
* Licensed under the MIT License. |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var copy = require('object-copy'); |
|
var define = require('define-property'); |
|
var util = require('util'); |
|
|
|
/** |
|
* Returns a function for extending the static properties, |
|
* prototype properties, and descriptors from the `Parent` |
|
* constructor onto `Child` constructors. |
|
* |
|
* ```js |
|
* var extend = require('static-extend'); |
|
* Parent.extend = extend(Parent); |
|
* |
|
* // optionally pass a custom merge function as the second arg |
|
* Parent.extend = extend(Parent, function(Child) { |
|
* Child.prototype.mixin = function(key, val) { |
|
* Child.prototype[key] = val; |
|
* }; |
|
* }); |
|
* |
|
* // extend "child" constructors |
|
* Parent.extend(Child); |
|
* |
|
* // optionally define prototype methods as the second arg |
|
* Parent.extend(Child, { |
|
* foo: function() {}, |
|
* bar: function() {} |
|
* }); |
|
* ``` |
|
* @param {Function} `Parent` Parent ctor |
|
* @param {Function} `extendFn` Optional extend function for handling any necessary custom merging. Useful when updating methods that require a specific prototype. |
|
* @param {Function} `Child` Child ctor |
|
* @param {Object} `proto` Optionally pass additional prototype properties to inherit. |
|
* @return {Object} |
|
* @api public |
|
*/ |
|
|
|
function extend(Parent, extendFn) { |
|
if (typeof Parent !== 'function') { |
|
throw new TypeError('expected Parent to be a function.'); |
|
} |
|
|
|
return function(Ctor, proto) { |
|
if (typeof Ctor !== 'function') { |
|
throw new TypeError('expected Ctor to be a function.'); |
|
} |
|
|
|
util.inherits(Ctor, Parent); |
|
copy(Ctor, Parent); |
|
|
|
// proto can be null or a plain object |
|
if (typeof proto === 'object') { |
|
var obj = Object.create(proto); |
|
|
|
for (var k in obj) { |
|
Ctor.prototype[k] = obj[k]; |
|
} |
|
} |
|
|
|
// keep a reference to the parent prototype |
|
define(Ctor.prototype, '_parent_', { |
|
configurable: true, |
|
set: function() {}, |
|
get: function() { |
|
return Parent.prototype; |
|
} |
|
}); |
|
|
|
if (typeof extendFn === 'function') { |
|
extendFn(Ctor, Parent); |
|
} |
|
|
|
Ctor.extend = extend(Ctor, extendFn); |
|
}; |
|
}; |
|
|
|
/** |
|
* Expose `extend` |
|
*/ |
|
|
|
module.exports = extend;
|
|
|