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