프로젝트

일반

사용자정보

통계
| 개정판:

root / HServer / 00.Server / 00.Program / node_modules / lodash.get / index.js

이력 | 보기 | 이력해설 | 다운로드 (22.8 KB)

1 39 HKM
/**
2
 * lodash (Custom Build) <https://lodash.com/>
3
 * Build: `lodash modularize exports="npm" -o ./`
4
 * Copyright jQuery Foundation and other contributors <https://jquery.org/>
5
 * Released under MIT license <https://lodash.com/license>
6
 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
7
 * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
8
 */
9
10
/** Used as the `TypeError` message for "Functions" methods. */
11
var FUNC_ERROR_TEXT = 'Expected a function';
12
13
/** Used to stand-in for `undefined` hash values. */
14
var HASH_UNDEFINED = '__lodash_hash_undefined__';
15
16
/** Used as references for various `Number` constants. */
17
var INFINITY = 1 / 0;
18
19
/** `Object#toString` result references. */
20
var funcTag = '[object Function]',
21
    genTag = '[object GeneratorFunction]',
22
    symbolTag = '[object Symbol]';
23
24
/** Used to match property names within property paths. */
25
var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
26
    reIsPlainProp = /^\w*$/,
27
    reLeadingDot = /^\./,
28
    rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;
29
30
/**
31
 * Used to match `RegExp`
32
 * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
33
 */
34
var reRegExpChar = /[\\^$.*+?()[\]{}|]/g;
35
36
/** Used to match backslashes in property paths. */
37
var reEscapeChar = /\\(\\)?/g;
38
39
/** Used to detect host constructors (Safari). */
40
var reIsHostCtor = /^\[object .+?Constructor\]$/;
41
42
/** Detect free variable `global` from Node.js. */
43
var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
44
45
/** Detect free variable `self`. */
46
var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
47
48
/** Used as a reference to the global object. */
49
var root = freeGlobal || freeSelf || Function('return this')();
50
51
/**
52
 * Gets the value at `key` of `object`.
53
 *
54
 * @private
55
 * @param {Object} [object] The object to query.
56
 * @param {string} key The key of the property to get.
57
 * @returns {*} Returns the property value.
58
 */
59
function getValue(object, key) {
60
  return object == null ? undefined : object[key];
61
}
62
63
/**
64
 * Checks if `value` is a host object in IE < 9.
65
 *
66
 * @private
67
 * @param {*} value The value to check.
68
 * @returns {boolean} Returns `true` if `value` is a host object, else `false`.
69
 */
70
function isHostObject(value) {
71
  // Many host objects are `Object` objects that can coerce to strings
72
  // despite having improperly defined `toString` methods.
73
  var result = false;
74
  if (value != null && typeof value.toString != 'function') {
75
    try {
76
      result = !!(value + '');
77
    } catch (e) {}
78
  }
79
  return result;
80
}
81
82
/** Used for built-in method references. */
83
var arrayProto = Array.prototype,
84
    funcProto = Function.prototype,
85
    objectProto = Object.prototype;
86
87
/** Used to detect overreaching core-js shims. */
88
var coreJsData = root['__core-js_shared__'];
89
90
/** Used to detect methods masquerading as native. */
91
var maskSrcKey = (function() {
92
  var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');
93
  return uid ? ('Symbol(src)_1.' + uid) : '';
94
}());
95
96
/** Used to resolve the decompiled source of functions. */
97
var funcToString = funcProto.toString;
98
99
/** Used to check objects for own properties. */
100
var hasOwnProperty = objectProto.hasOwnProperty;
101
102
/**
103
 * Used to resolve the
104
 * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
105
 * of values.
106
 */
107
var objectToString = objectProto.toString;
108
109
/** Used to detect if a method is native. */
110
var reIsNative = RegExp('^' +
111
  funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')
112
  .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
113
);
114
115
/** Built-in value references. */
116
var Symbol = root.Symbol,
117
    splice = arrayProto.splice;
118
119
/* Built-in method references that are verified to be native. */
120
var Map = getNative(root, 'Map'),
121
    nativeCreate = getNative(Object, 'create');
122
123
/** Used to convert symbols to primitives and strings. */
124
var symbolProto = Symbol ? Symbol.prototype : undefined,
125
    symbolToString = symbolProto ? symbolProto.toString : undefined;
126
127
/**
128
 * Creates a hash object.
129
 *
130
 * @private
131
 * @constructor
132
 * @param {Array} [entries] The key-value pairs to cache.
133
 */
134
function Hash(entries) {
135
  var index = -1,
136
      length = entries ? entries.length : 0;
137
138
  this.clear();
139
  while (++index < length) {
140
    var entry = entries[index];
141
    this.set(entry[0], entry[1]);
142
  }
143
}
144
145
/**
146
 * Removes all key-value entries from the hash.
147
 *
148
 * @private
149
 * @name clear
150
 * @memberOf Hash
151
 */
152
function hashClear() {
153
  this.__data__ = nativeCreate ? nativeCreate(null) : {};
154
}
155
156
/**
157
 * Removes `key` and its value from the hash.
158
 *
159
 * @private
160
 * @name delete
161
 * @memberOf Hash
162
 * @param {Object} hash The hash to modify.
163
 * @param {string} key The key of the value to remove.
164
 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
165
 */
166
function hashDelete(key) {
167
  return this.has(key) && delete this.__data__[key];
168
}
169
170
/**
171
 * Gets the hash value for `key`.
172
 *
173
 * @private
174
 * @name get
175
 * @memberOf Hash
176
 * @param {string} key The key of the value to get.
177
 * @returns {*} Returns the entry value.
178
 */
179
function hashGet(key) {
180
  var data = this.__data__;
181
  if (nativeCreate) {
182
    var result = data[key];
183
    return result === HASH_UNDEFINED ? undefined : result;
184
  }
185
  return hasOwnProperty.call(data, key) ? data[key] : undefined;
186
}
187
188
/**
189
 * Checks if a hash value for `key` exists.
190
 *
191
 * @private
192
 * @name has
193
 * @memberOf Hash
194
 * @param {string} key The key of the entry to check.
195
 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
196
 */
197
function hashHas(key) {
198
  var data = this.__data__;
199
  return nativeCreate ? data[key] !== undefined : hasOwnProperty.call(data, key);
200
}
201
202
/**
203
 * Sets the hash `key` to `value`.
204
 *
205
 * @private
206
 * @name set
207
 * @memberOf Hash
208
 * @param {string} key The key of the value to set.
209
 * @param {*} value The value to set.
210
 * @returns {Object} Returns the hash instance.
211
 */
212
function hashSet(key, value) {
213
  var data = this.__data__;
214
  data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
215
  return this;
216
}
217
218
// Add methods to `Hash`.
219
Hash.prototype.clear = hashClear;
220
Hash.prototype['delete'] = hashDelete;
221
Hash.prototype.get = hashGet;
222
Hash.prototype.has = hashHas;
223
Hash.prototype.set = hashSet;
224
225
/**
226
 * Creates an list cache object.
227
 *
228
 * @private
229
 * @constructor
230
 * @param {Array} [entries] The key-value pairs to cache.
231
 */
232
function ListCache(entries) {
233
  var index = -1,
234
      length = entries ? entries.length : 0;
235
236
  this.clear();
237
  while (++index < length) {
238
    var entry = entries[index];
239
    this.set(entry[0], entry[1]);
240
  }
241
}
242
243
/**
244
 * Removes all key-value entries from the list cache.
245
 *
246
 * @private
247
 * @name clear
248
 * @memberOf ListCache
249
 */
250
function listCacheClear() {
251
  this.__data__ = [];
252
}
253
254
/**
255
 * Removes `key` and its value from the list cache.
256
 *
257
 * @private
258
 * @name delete
259
 * @memberOf ListCache
260
 * @param {string} key The key of the value to remove.
261
 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
262
 */
263
function listCacheDelete(key) {
264
  var data = this.__data__,
265
      index = assocIndexOf(data, key);
266
267
  if (index < 0) {
268
    return false;
269
  }
270
  var lastIndex = data.length - 1;
271
  if (index == lastIndex) {
272
    data.pop();
273
  } else {
274
    splice.call(data, index, 1);
275
  }
276
  return true;
277
}
278
279
/**
280
 * Gets the list cache value for `key`.
281
 *
282
 * @private
283
 * @name get
284
 * @memberOf ListCache
285
 * @param {string} key The key of the value to get.
286
 * @returns {*} Returns the entry value.
287
 */
288
function listCacheGet(key) {
289
  var data = this.__data__,
290
      index = assocIndexOf(data, key);
291
292
  return index < 0 ? undefined : data[index][1];
293
}
294
295
/**
296
 * Checks if a list cache value for `key` exists.
297
 *
298
 * @private
299
 * @name has
300
 * @memberOf ListCache
301
 * @param {string} key The key of the entry to check.
302
 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
303
 */
304
function listCacheHas(key) {
305
  return assocIndexOf(this.__data__, key) > -1;
306
}
307
308
/**
309
 * Sets the list cache `key` to `value`.
310
 *
311
 * @private
312
 * @name set
313
 * @memberOf ListCache
314
 * @param {string} key The key of the value to set.
315
 * @param {*} value The value to set.
316
 * @returns {Object} Returns the list cache instance.
317
 */
318
function listCacheSet(key, value) {
319
  var data = this.__data__,
320
      index = assocIndexOf(data, key);
321
322
  if (index < 0) {
323
    data.push([key, value]);
324
  } else {
325
    data[index][1] = value;
326
  }
327
  return this;
328
}
329
330
// Add methods to `ListCache`.
331
ListCache.prototype.clear = listCacheClear;
332
ListCache.prototype['delete'] = listCacheDelete;
333
ListCache.prototype.get = listCacheGet;
334
ListCache.prototype.has = listCacheHas;
335
ListCache.prototype.set = listCacheSet;
336
337
/**
338
 * Creates a map cache object to store key-value pairs.
339
 *
340
 * @private
341
 * @constructor
342
 * @param {Array} [entries] The key-value pairs to cache.
343
 */
344
function MapCache(entries) {
345
  var index = -1,
346
      length = entries ? entries.length : 0;
347
348
  this.clear();
349
  while (++index < length) {
350
    var entry = entries[index];
351
    this.set(entry[0], entry[1]);
352
  }
353
}
354
355
/**
356
 * Removes all key-value entries from the map.
357
 *
358
 * @private
359
 * @name clear
360
 * @memberOf MapCache
361
 */
362
function mapCacheClear() {
363
  this.__data__ = {
364
    'hash': new Hash,
365
    'map': new (Map || ListCache),
366
    'string': new Hash
367
  };
368
}
369
370
/**
371
 * Removes `key` and its value from the map.
372
 *
373
 * @private
374
 * @name delete
375
 * @memberOf MapCache
376
 * @param {string} key The key of the value to remove.
377
 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
378
 */
379
function mapCacheDelete(key) {
380
  return getMapData(this, key)['delete'](key);
381
}
382
383
/**
384
 * Gets the map value for `key`.
385
 *
386
 * @private
387
 * @name get
388
 * @memberOf MapCache
389
 * @param {string} key The key of the value to get.
390
 * @returns {*} Returns the entry value.
391
 */
392
function mapCacheGet(key) {
393
  return getMapData(this, key).get(key);
394
}
395
396
/**
397
 * Checks if a map value for `key` exists.
398
 *
399
 * @private
400
 * @name has
401
 * @memberOf MapCache
402
 * @param {string} key The key of the entry to check.
403
 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
404
 */
405
function mapCacheHas(key) {
406
  return getMapData(this, key).has(key);
407
}
408
409
/**
410
 * Sets the map `key` to `value`.
411
 *
412
 * @private
413
 * @name set
414
 * @memberOf MapCache
415
 * @param {string} key The key of the value to set.
416
 * @param {*} value The value to set.
417
 * @returns {Object} Returns the map cache instance.
418
 */
419
function mapCacheSet(key, value) {
420
  getMapData(this, key).set(key, value);
421
  return this;
422
}
423
424
// Add methods to `MapCache`.
425
MapCache.prototype.clear = mapCacheClear;
426
MapCache.prototype['delete'] = mapCacheDelete;
427
MapCache.prototype.get = mapCacheGet;
428
MapCache.prototype.has = mapCacheHas;
429
MapCache.prototype.set = mapCacheSet;
430
431
/**
432
 * Gets the index at which the `key` is found in `array` of key-value pairs.
433
 *
434
 * @private
435
 * @param {Array} array The array to inspect.
436
 * @param {*} key The key to search for.
437
 * @returns {number} Returns the index of the matched value, else `-1`.
438
 */
439
function assocIndexOf(array, key) {
440
  var length = array.length;
441
  while (length--) {
442
    if (eq(array[length][0], key)) {
443
      return length;
444
    }
445
  }
446
  return -1;
447
}
448
449
/**
450
 * The base implementation of `_.get` without support for default values.
451
 *
452
 * @private
453
 * @param {Object} object The object to query.
454
 * @param {Array|string} path The path of the property to get.
455
 * @returns {*} Returns the resolved value.
456
 */
457
function baseGet(object, path) {
458
  path = isKey(path, object) ? [path] : castPath(path);
459
460
  var index = 0,
461
      length = path.length;
462
463
  while (object != null && index < length) {
464
    object = object[toKey(path[index++])];
465
  }
466
  return (index && index == length) ? object : undefined;
467
}
468
469
/**
470
 * The base implementation of `_.isNative` without bad shim checks.
471
 *
472
 * @private
473
 * @param {*} value The value to check.
474
 * @returns {boolean} Returns `true` if `value` is a native function,
475
 *  else `false`.
476
 */
477
function baseIsNative(value) {
478
  if (!isObject(value) || isMasked(value)) {
479
    return false;
480
  }
481
  var pattern = (isFunction(value) || isHostObject(value)) ? reIsNative : reIsHostCtor;
482
  return pattern.test(toSource(value));
483
}
484
485
/**
486
 * The base implementation of `_.toString` which doesn't convert nullish
487
 * values to empty strings.
488
 *
489
 * @private
490
 * @param {*} value The value to process.
491
 * @returns {string} Returns the string.
492
 */
493
function baseToString(value) {
494
  // Exit early for strings to avoid a performance hit in some environments.
495
  if (typeof value == 'string') {
496
    return value;
497
  }
498
  if (isSymbol(value)) {
499
    return symbolToString ? symbolToString.call(value) : '';
500
  }
501
  var result = (value + '');
502
  return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
503
}
504
505
/**
506
 * Casts `value` to a path array if it's not one.
507
 *
508
 * @private
509
 * @param {*} value The value to inspect.
510
 * @returns {Array} Returns the cast property path array.
511
 */
512
function castPath(value) {
513
  return isArray(value) ? value : stringToPath(value);
514
}
515
516
/**
517
 * Gets the data for `map`.
518
 *
519
 * @private
520
 * @param {Object} map The map to query.
521
 * @param {string} key The reference key.
522
 * @returns {*} Returns the map data.
523
 */
524
function getMapData(map, key) {
525
  var data = map.__data__;
526
  return isKeyable(key)
527
    ? data[typeof key == 'string' ? 'string' : 'hash']
528
    : data.map;
529
}
530
531
/**
532
 * Gets the native function at `key` of `object`.
533
 *
534
 * @private
535
 * @param {Object} object The object to query.
536
 * @param {string} key The key of the method to get.
537
 * @returns {*} Returns the function if it's native, else `undefined`.
538
 */
539
function getNative(object, key) {
540
  var value = getValue(object, key);
541
  return baseIsNative(value) ? value : undefined;
542
}
543
544
/**
545
 * Checks if `value` is a property name and not a property path.
546
 *
547
 * @private
548
 * @param {*} value The value to check.
549
 * @param {Object} [object] The object to query keys on.
550
 * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
551
 */
552
function isKey(value, object) {
553
  if (isArray(value)) {
554
    return false;
555
  }
556
  var type = typeof value;
557
  if (type == 'number' || type == 'symbol' || type == 'boolean' ||
558
      value == null || isSymbol(value)) {
559
    return true;
560
  }
561
  return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
562
    (object != null && value in Object(object));
563
}
564
565
/**
566
 * Checks if `value` is suitable for use as unique object key.
567
 *
568
 * @private
569
 * @param {*} value The value to check.
570
 * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
571
 */
572
function isKeyable(value) {
573
  var type = typeof value;
574
  return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
575
    ? (value !== '__proto__')
576
    : (value === null);
577
}
578
579
/**
580
 * Checks if `func` has its source masked.
581
 *
582
 * @private
583
 * @param {Function} func The function to check.
584
 * @returns {boolean} Returns `true` if `func` is masked, else `false`.
585
 */
586
function isMasked(func) {
587
  return !!maskSrcKey && (maskSrcKey in func);
588
}
589
590
/**
591
 * Converts `string` to a property path array.
592
 *
593
 * @private
594
 * @param {string} string The string to convert.
595
 * @returns {Array} Returns the property path array.
596
 */
597
var stringToPath = memoize(function(string) {
598
  string = toString(string);
599
600
  var result = [];
601
  if (reLeadingDot.test(string)) {
602
    result.push('');
603
  }
604
  string.replace(rePropName, function(match, number, quote, string) {
605
    result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));
606
  });
607
  return result;
608
});
609
610
/**
611
 * Converts `value` to a string key if it's not a string or symbol.
612
 *
613
 * @private
614
 * @param {*} value The value to inspect.
615
 * @returns {string|symbol} Returns the key.
616
 */
617
function toKey(value) {
618
  if (typeof value == 'string' || isSymbol(value)) {
619
    return value;
620
  }
621
  var result = (value + '');
622
  return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
623
}
624
625
/**
626
 * Converts `func` to its source code.
627
 *
628
 * @private
629
 * @param {Function} func The function to process.
630
 * @returns {string} Returns the source code.
631
 */
632
function toSource(func) {
633
  if (func != null) {
634
    try {
635
      return funcToString.call(func);
636
    } catch (e) {}
637
    try {
638
      return (func + '');
639
    } catch (e) {}
640
  }
641
  return '';
642
}
643
644
/**
645
 * Creates a function that memoizes the result of `func`. If `resolver` is
646
 * provided, it determines the cache key for storing the result based on the
647
 * arguments provided to the memoized function. By default, the first argument
648
 * provided to the memoized function is used as the map cache key. The `func`
649
 * is invoked with the `this` binding of the memoized function.
650
 *
651
 * **Note:** The cache is exposed as the `cache` property on the memoized
652
 * function. Its creation may be customized by replacing the `_.memoize.Cache`
653
 * constructor with one whose instances implement the
654
 * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)
655
 * method interface of `delete`, `get`, `has`, and `set`.
656
 *
657
 * @static
658
 * @memberOf _
659
 * @since 0.1.0
660
 * @category Function
661
 * @param {Function} func The function to have its output memoized.
662
 * @param {Function} [resolver] The function to resolve the cache key.
663
 * @returns {Function} Returns the new memoized function.
664
 * @example
665
 *
666
 * var object = { 'a': 1, 'b': 2 };
667
 * var other = { 'c': 3, 'd': 4 };
668
 *
669
 * var values = _.memoize(_.values);
670
 * values(object);
671
 * // => [1, 2]
672
 *
673
 * values(other);
674
 * // => [3, 4]
675
 *
676
 * object.a = 2;
677
 * values(object);
678
 * // => [1, 2]
679
 *
680
 * // Modify the result cache.
681
 * values.cache.set(object, ['a', 'b']);
682
 * values(object);
683
 * // => ['a', 'b']
684
 *
685
 * // Replace `_.memoize.Cache`.
686
 * _.memoize.Cache = WeakMap;
687
 */
688
function memoize(func, resolver) {
689
  if (typeof func != 'function' || (resolver && typeof resolver != 'function')) {
690
    throw new TypeError(FUNC_ERROR_TEXT);
691
  }
692
  var memoized = function() {
693
    var args = arguments,
694
        key = resolver ? resolver.apply(this, args) : args[0],
695
        cache = memoized.cache;
696
697
    if (cache.has(key)) {
698
      return cache.get(key);
699
    }
700
    var result = func.apply(this, args);
701
    memoized.cache = cache.set(key, result);
702
    return result;
703
  };
704
  memoized.cache = new (memoize.Cache || MapCache);
705
  return memoized;
706
}
707
708
// Assign cache to `_.memoize`.
709
memoize.Cache = MapCache;
710
711
/**
712
 * Performs a
713
 * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
714
 * comparison between two values to determine if they are equivalent.
715
 *
716
 * @static
717
 * @memberOf _
718
 * @since 4.0.0
719
 * @category Lang
720
 * @param {*} value The value to compare.
721
 * @param {*} other The other value to compare.
722
 * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
723
 * @example
724
 *
725
 * var object = { 'a': 1 };
726
 * var other = { 'a': 1 };
727
 *
728
 * _.eq(object, object);
729
 * // => true
730
 *
731
 * _.eq(object, other);
732
 * // => false
733
 *
734
 * _.eq('a', 'a');
735
 * // => true
736
 *
737
 * _.eq('a', Object('a'));
738
 * // => false
739
 *
740
 * _.eq(NaN, NaN);
741
 * // => true
742
 */
743
function eq(value, other) {
744
  return value === other || (value !== value && other !== other);
745
}
746
747
/**
748
 * Checks if `value` is classified as an `Array` object.
749
 *
750
 * @static
751
 * @memberOf _
752
 * @since 0.1.0
753
 * @category Lang
754
 * @param {*} value The value to check.
755
 * @returns {boolean} Returns `true` if `value` is an array, else `false`.
756
 * @example
757
 *
758
 * _.isArray([1, 2, 3]);
759
 * // => true
760
 *
761
 * _.isArray(document.body.children);
762
 * // => false
763
 *
764
 * _.isArray('abc');
765
 * // => false
766
 *
767
 * _.isArray(_.noop);
768
 * // => false
769
 */
770
var isArray = Array.isArray;
771
772
/**
773
 * Checks if `value` is classified as a `Function` object.
774
 *
775
 * @static
776
 * @memberOf _
777
 * @since 0.1.0
778
 * @category Lang
779
 * @param {*} value The value to check.
780
 * @returns {boolean} Returns `true` if `value` is a function, else `false`.
781
 * @example
782
 *
783
 * _.isFunction(_);
784
 * // => true
785
 *
786
 * _.isFunction(/abc/);
787
 * // => false
788
 */
789
function isFunction(value) {
790
  // The use of `Object#toString` avoids issues with the `typeof` operator
791
  // in Safari 8-9 which returns 'object' for typed array and other constructors.
792
  var tag = isObject(value) ? objectToString.call(value) : '';
793
  return tag == funcTag || tag == genTag;
794
}
795
796
/**
797
 * Checks if `value` is the
798
 * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
799
 * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
800
 *
801
 * @static
802
 * @memberOf _
803
 * @since 0.1.0
804
 * @category Lang
805
 * @param {*} value The value to check.
806
 * @returns {boolean} Returns `true` if `value` is an object, else `false`.
807
 * @example
808
 *
809
 * _.isObject({});
810
 * // => true
811
 *
812
 * _.isObject([1, 2, 3]);
813
 * // => true
814
 *
815
 * _.isObject(_.noop);
816
 * // => true
817
 *
818
 * _.isObject(null);
819
 * // => false
820
 */
821
function isObject(value) {
822
  var type = typeof value;
823
  return !!value && (type == 'object' || type == 'function');
824
}
825
826
/**
827
 * Checks if `value` is object-like. A value is object-like if it's not `null`
828
 * and has a `typeof` result of "object".
829
 *
830
 * @static
831
 * @memberOf _
832
 * @since 4.0.0
833
 * @category Lang
834
 * @param {*} value The value to check.
835
 * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
836
 * @example
837
 *
838
 * _.isObjectLike({});
839
 * // => true
840
 *
841
 * _.isObjectLike([1, 2, 3]);
842
 * // => true
843
 *
844
 * _.isObjectLike(_.noop);
845
 * // => false
846
 *
847
 * _.isObjectLike(null);
848
 * // => false
849
 */
850
function isObjectLike(value) {
851
  return !!value && typeof value == 'object';
852
}
853
854
/**
855
 * Checks if `value` is classified as a `Symbol` primitive or object.
856
 *
857
 * @static
858
 * @memberOf _
859
 * @since 4.0.0
860
 * @category Lang
861
 * @param {*} value The value to check.
862
 * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
863
 * @example
864
 *
865
 * _.isSymbol(Symbol.iterator);
866
 * // => true
867
 *
868
 * _.isSymbol('abc');
869
 * // => false
870
 */
871
function isSymbol(value) {
872
  return typeof value == 'symbol' ||
873
    (isObjectLike(value) && objectToString.call(value) == symbolTag);
874
}
875
876
/**
877
 * Converts `value` to a string. An empty string is returned for `null`
878
 * and `undefined` values. The sign of `-0` is preserved.
879
 *
880
 * @static
881
 * @memberOf _
882
 * @since 4.0.0
883
 * @category Lang
884
 * @param {*} value The value to process.
885
 * @returns {string} Returns the string.
886
 * @example
887
 *
888
 * _.toString(null);
889
 * // => ''
890
 *
891
 * _.toString(-0);
892
 * // => '-0'
893
 *
894
 * _.toString([1, 2, 3]);
895
 * // => '1,2,3'
896
 */
897
function toString(value) {
898
  return value == null ? '' : baseToString(value);
899
}
900
901
/**
902
 * Gets the value at `path` of `object`. If the resolved value is
903
 * `undefined`, the `defaultValue` is returned in its place.
904
 *
905
 * @static
906
 * @memberOf _
907
 * @since 3.7.0
908
 * @category Object
909
 * @param {Object} object The object to query.
910
 * @param {Array|string} path The path of the property to get.
911
 * @param {*} [defaultValue] The value returned for `undefined` resolved values.
912
 * @returns {*} Returns the resolved value.
913
 * @example
914
 *
915
 * var object = { 'a': [{ 'b': { 'c': 3 } }] };
916
 *
917
 * _.get(object, 'a[0].b.c');
918
 * // => 3
919
 *
920
 * _.get(object, ['a', '0', 'b', 'c']);
921
 * // => 3
922
 *
923
 * _.get(object, 'a.b.c', 'default');
924
 * // => 'default'
925
 */
926
function get(object, path, defaultValue) {
927
  var result = object == null ? undefined : baseGet(object, path);
928
  return result === undefined ? defaultValue : result;
929
}
930
931
module.exports = get;