在express.js里 我们看到这样的代码:
顾名思义,我们知道是将proto,EventEmitter.prototype 上的属性复制一份给app上。
那它具体实现的原理是怎么样的?
1 'use strict' 2 3 /** 4 * Module exports. 5 * @public 6 */ 7 8 module.exports = merge 9 10 /** 11 * Module variables. 12 * @private 13 */ 14 15 var hasOwnProperty = Object.prototype.hasOwnProperty 16 17 /** 18 * Merge the property descriptors of `src` into `dest` 19 * 20 * @param {object} dest Object to add descriptors to 21 * @param {object} src Object to clone descriptors from 22 * @param {boolean} [redefine=true] Redefine `dest` properties with `src` properties 23 * @returns {object} Reference to dest 24 * @public 25 */ 26 27 function merge(dest, src, redefine) { 28 29 //dest和src 必须传 30 if (!dest) { 31 throw new TypeError('argument dest is required') 32 } 33 34 if (!src) { 35 throw new TypeError('argument src is required') 36 } 37 38 39 //不传默认是true 40 if (redefine === undefined) { 41 42 redefine = true 43 } 44 45 //遍历src本身所有的属性。不包括它原型上的。 46 //为什么是所有的。Object.keys() , for....in 都是枚举可枚举的属性 47 //而Object.getOwnPropertyNames不管可不可枚举都可以取出来 48 49 Object.getOwnPropertyNames(src).forEach(function forEachOwnPropertyName(name) { 50 51 //如果传过来的redefine是true,不管你这个对象本身有没有已经定义这个属性 52 //都会覆盖! 53 54 //如果是false,没有才加上! 55 //而且是原原本本的复制,他会取出描述器,一模一样加上! 56 57 if (!redefine && hasOwnProperty.call(dest, name)) { 58 // Skip desriptor 59 return 60 } 61 62 // Copy descriptor 63 var descriptor = Object.getOwnPropertyDescriptor(src, name) 64 Object.defineProperty(dest, name, descriptor) 65 }) 66 67 return dest 68 }