91 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			91 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /*!
 | |
|  * 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;
 |