|
|
- /*!
- * 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;
|