You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							162 lines
						
					
					
						
							2.9 KiB
						
					
					
				
			
		
		
	
	
							162 lines
						
					
					
						
							2.9 KiB
						
					
					
				| /*!
 | |
|  * copy-to - index.js
 | |
|  * Copyright(c) 2014 dead_horse <dead_horse@qq.com>
 | |
|  * MIT Licensed
 | |
|  */
 | |
| 
 | |
| 'use strict';
 | |
| 
 | |
| /**
 | |
|  * slice() reference.
 | |
|  */
 | |
| 
 | |
| var slice = Array.prototype.slice;
 | |
| 
 | |
| /**
 | |
|  * Expose copy
 | |
|  *
 | |
|  * ```
 | |
|  * copy({foo: 'nar', hello: 'copy'}).to({hello: 'world'});
 | |
|  * copy({foo: 'nar', hello: 'copy'}).toCover({hello: 'world'});
 | |
|  * ```
 | |
|  *
 | |
|  * @param {Object} src
 | |
|  * @return {Copy}
 | |
|  */
 | |
| 
 | |
| module.exports = Copy;
 | |
| 
 | |
| 
 | |
| /**
 | |
|  * Copy
 | |
|  * @param {Object} src
 | |
|  * @param {Boolean} withAccess
 | |
|  */
 | |
| 
 | |
| function Copy(src, withAccess) {
 | |
|   if (!(this instanceof Copy)) return new Copy(src, withAccess);
 | |
|   this.src = src;
 | |
|   this._withAccess = withAccess;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * copy properties include getter and setter
 | |
|  * @param {[type]} val [description]
 | |
|  * @return {[type]} [description]
 | |
|  */
 | |
| 
 | |
| Copy.prototype.withAccess = function (w) {
 | |
|   this._withAccess = w !== false;
 | |
|   return this;
 | |
| };
 | |
| 
 | |
| /**
 | |
|  * pick keys in src
 | |
|  *
 | |
|  * @api: public
 | |
|  */
 | |
| 
 | |
| Copy.prototype.pick = function(keys) {
 | |
|   if (!Array.isArray(keys)) {
 | |
|     keys = slice.call(arguments);
 | |
|   }
 | |
|   if (keys.length) {
 | |
|     this.keys = keys;
 | |
|   }
 | |
|   return this;
 | |
| };
 | |
| 
 | |
| /**
 | |
|  * copy src to target,
 | |
|  * do not cover any property target has
 | |
|  * @param {Object} to
 | |
|  *
 | |
|  * @api: public
 | |
|  */
 | |
| 
 | |
| Copy.prototype.to = function(to) {
 | |
|   to = to || {};
 | |
| 
 | |
|   if (!this.src) return to;
 | |
|   var keys = this.keys || Object.keys(this.src);
 | |
| 
 | |
|   if (!this._withAccess) {
 | |
|     for (var i = 0; i < keys.length; i++) {
 | |
|       key = keys[i];
 | |
|       if (to[key] !== undefined) continue;
 | |
|       to[key] = this.src[key];
 | |
|     }
 | |
|     return to;
 | |
|   }
 | |
| 
 | |
|   for (var i = 0; i < keys.length; i++) {
 | |
|     var key = keys[i];
 | |
|     if (!notDefined(to, key)) continue;
 | |
|     var getter = this.src.__lookupGetter__(key);
 | |
|     var setter = this.src.__lookupSetter__(key);
 | |
|     if (getter) to.__defineGetter__(key, getter);
 | |
|     if (setter) to.__defineSetter__(key, setter);
 | |
| 
 | |
|     if (!getter && !setter) {
 | |
|       to[key] = this.src[key];
 | |
|     }
 | |
|   }
 | |
|   return to;
 | |
| };
 | |
| 
 | |
| /**
 | |
|  * copy src to target,
 | |
|  * override any property target has
 | |
|  * @param {Object} to
 | |
|  *
 | |
|  * @api: public
 | |
|  */
 | |
| 
 | |
| Copy.prototype.toCover = function(to) {
 | |
|   var keys = this.keys || Object.keys(this.src);
 | |
| 
 | |
|   for (var i = 0; i < keys.length; i++) {
 | |
|     var key = keys[i];
 | |
|     delete to[key];
 | |
|     var getter = this.src.__lookupGetter__(key);
 | |
|     var setter = this.src.__lookupSetter__(key);
 | |
|     if (getter) to.__defineGetter__(key, getter);
 | |
|     if (setter) to.__defineSetter__(key, setter);
 | |
| 
 | |
|     if (!getter && !setter) {
 | |
|       to[key] = this.src[key];
 | |
|     }
 | |
|   }
 | |
| };
 | |
| 
 | |
| Copy.prototype.override = Copy.prototype.toCover;
 | |
| 
 | |
| /**
 | |
|  * append another object to src
 | |
|  * @param {Obj} obj
 | |
|  * @return {Copy}
 | |
|  */
 | |
| 
 | |
| Copy.prototype.and = function (obj) {
 | |
|   var src = {};
 | |
|   this.to(src);
 | |
|   this.src = obj;
 | |
|   this.to(src);
 | |
|   this.src = src;
 | |
| 
 | |
|   return this;
 | |
| };
 | |
| 
 | |
| /**
 | |
|  * check obj[key] if not defiend
 | |
|  * @param {Object} obj
 | |
|  * @param {String} key
 | |
|  * @return {Boolean}
 | |
|  */
 | |
| 
 | |
| function notDefined(obj, key) {
 | |
|   return obj[key] === undefined
 | |
|     && obj.__lookupGetter__(key) === undefined
 | |
|     && obj.__lookupSetter__(key) === undefined;
 | |
| }
 |