inherit.js (2913B)
1 /** 2 * @license Apache-2.0 3 * 4 * Copyright (c) 2018 The Stdlib Authors. 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19 'use strict'; 20 21 // MODULES // 22 23 var defineProperty = require( './../../define-property' ); 24 var validate = require( './validate.js' ); 25 var createObject = require( './detect.js' ); 26 27 28 // MAIN // 29 30 /** 31 * Implements prototypical inheritance by replacing the prototype of one constructor with the prototype of another constructor. 32 * 33 * ## Notes 34 * 35 * - This implementation is not designed to work with ES2015/ES6 classes. For ES2015/ES6 classes, use `class` with `extends`. 36 * - For reference, see [node#3455](https://github.com/nodejs/node/pull/3455), [node#4179](https://github.com/nodejs/node/issues/4179), [node#3452](https://github.com/nodejs/node/issues/3452), and [node commit](https://github.com/nodejs/node/commit/29da8cf8d7ab8f66b9091ab22664067d4468461e#diff-3deb3f32958bb937ae05c6f3e4abbdf5). 37 * 38 * 39 * @param {(Object|Function)} ctor - constructor which will inherit 40 * @param {(Object|Function)} superCtor - super (parent) constructor 41 * @throws {TypeError} first argument must be either an object or a function which can inherit 42 * @throws {TypeError} second argument must be either an object or a function from which a constructor can inherit 43 * @throws {TypeError} second argument must have an inheritable prototype 44 * @returns {(Object|Function)} child constructor 45 * 46 * @example 47 * function Foo() { 48 * return this; 49 * } 50 * Foo.prototype.beep = function beep() { 51 * return 'boop'; 52 * }; 53 * 54 * function Bar() { 55 * Foo.call( this ); 56 * return this; 57 * } 58 * inherit( Bar, Foo ); 59 * 60 * var bar = new Bar(); 61 * var v = bar.beep(); 62 * // returns 'boop' 63 */ 64 function inherit( ctor, superCtor ) { 65 var err = validate( ctor ); 66 if ( err ) { 67 throw err; 68 } 69 err = validate( superCtor ); 70 if ( err ) { 71 throw err; 72 } 73 if ( typeof superCtor.prototype === 'undefined' ) { 74 throw new TypeError( 'invalid argument. Second argument must have a prototype from which another object can inherit. Value: `'+superCtor.prototype+'`.' ); 75 } 76 // Create a prototype which inherits from the parent prototype: 77 ctor.prototype = createObject( superCtor.prototype ); 78 79 // Set the constructor to refer to the child constructor: 80 defineProperty( ctor.prototype, 'constructor', { 81 'configurable': true, 82 'enumerable': false, 83 'writable': true, 84 'value': ctor 85 }); 86 87 return ctor; 88 } 89 90 91 // EXPORTS // 92 93 module.exports = inherit;