Projekt

Obecné

Profil

Stáhnout (3.34 KB) Statistiky
| Větev: | Revize:
1
'use strict';
2

    
3
var typeOf = require('kind-of');
4
var copyDescriptor = require('copy-descriptor');
5
var define = require('define-property');
6

    
7
/**
8
 * Copy static properties, prototype properties, and descriptors from one object to another.
9
 *
10
 * ```js
11
 * function App() {}
12
 * var proto = App.prototype;
13
 * App.prototype.set = function() {};
14
 * App.prototype.get = function() {};
15
 *
16
 * var obj = {};
17
 * copy(obj, proto);
18
 * ```
19
 * @param {Object} `receiver`
20
 * @param {Object} `provider`
21
 * @param {String|Array} `omit` One or more properties to omit
22
 * @return {Object}
23
 * @api public
24
 */
25

    
26
function copy(receiver, provider, omit) {
27
  if (!isObject(receiver)) {
28
    throw new TypeError('expected receiving object to be an object.');
29
  }
30
  if (!isObject(provider)) {
31
    throw new TypeError('expected providing object to be an object.');
32
  }
33

    
34
  var props = nativeKeys(provider);
35
  var keys = Object.keys(provider);
36
  var len = props.length;
37
  omit = arrayify(omit);
38

    
39
  while (len--) {
40
    var key = props[len];
41

    
42
    if (has(keys, key)) {
43
      define(receiver, key, provider[key]);
44
    } else if (!(key in receiver) && !has(omit, key)) {
45
      copyDescriptor(receiver, provider, key);
46
    }
47
  }
48
};
49

    
50
/**
51
 * Return true if the given value is an object or function
52
 */
53

    
54
function isObject(val) {
55
  return typeOf(val) === 'object' || typeof val === 'function';
56
}
57

    
58
/**
59
 * Returns true if an array has any of the given elements, or an
60
 * object has any of the give keys.
61
 *
62
 * ```js
63
 * has(['a', 'b', 'c'], 'c');
64
 * //=> true
65
 *
66
 * has(['a', 'b', 'c'], ['c', 'z']);
67
 * //=> true
68
 *
69
 * has({a: 'b', c: 'd'}, ['c', 'z']);
70
 * //=> true
71
 * ```
72
 * @param {Object} `obj`
73
 * @param {String|Array} `val`
74
 * @return {Boolean}
75
 */
76

    
77
function has(obj, val) {
78
  val = arrayify(val);
79
  var len = val.length;
80

    
81
  if (isObject(obj)) {
82
    for (var key in obj) {
83
      if (val.indexOf(key) > -1) {
84
        return true;
85
      }
86
    }
87

    
88
    var keys = nativeKeys(obj);
89
    return has(keys, val);
90
  }
91

    
92
  if (Array.isArray(obj)) {
93
    var arr = obj;
94
    while (len--) {
95
      if (arr.indexOf(val[len]) > -1) {
96
        return true;
97
      }
98
    }
99
    return false;
100
  }
101

    
102
  throw new TypeError('expected an array or object.');
103
}
104

    
105
/**
106
 * Cast the given value to an array.
107
 *
108
 * ```js
109
 * arrayify('foo');
110
 * //=> ['foo']
111
 *
112
 * arrayify(['foo']);
113
 * //=> ['foo']
114
 * ```
115
 *
116
 * @param {String|Array} `val`
117
 * @return {Array}
118
 */
119

    
120
function arrayify(val) {
121
  return val ? (Array.isArray(val) ? val : [val]) : [];
122
}
123

    
124
/**
125
 * Returns true if a value has a `contructor`
126
 *
127
 * ```js
128
 * hasConstructor({});
129
 * //=> true
130
 *
131
 * hasConstructor(Object.create(null));
132
 * //=> false
133
 * ```
134
 * @param  {Object} `value`
135
 * @return {Boolean}
136
 */
137

    
138
function hasConstructor(val) {
139
  return isObject(val) && typeof val.constructor !== 'undefined';
140
}
141

    
142
/**
143
 * Get the native `ownPropertyNames` from the constructor of the
144
 * given `object`. An empty array is returned if the object does
145
 * not have a constructor.
146
 *
147
 * ```js
148
 * nativeKeys({a: 'b', b: 'c', c: 'd'})
149
 * //=> ['a', 'b', 'c']
150
 *
151
 * nativeKeys(function(){})
152
 * //=> ['length', 'caller']
153
 * ```
154
 *
155
 * @param  {Object} `obj` Object that has a `constructor`.
156
 * @return {Array} Array of keys.
157
 */
158

    
159
function nativeKeys(val) {
160
  if (!hasConstructor(val)) return [];
161
  return Object.getOwnPropertyNames(val);
162
}
163

    
164
/**
165
 * Expose `copy`
166
 */
167

    
168
module.exports = copy;
169

    
170
/**
171
 * Expose `copy.has` for tests
172
 */
173

    
174
module.exports.has = has;
(2-2/3)