mirror of
https://github.com/whoisclebs/lodash.git
synced 2026-02-02 16:17:50 +00:00
Add support for symbols to _.clone, _.cloneDeep, and _.isEqual.
This commit is contained in:
38
lodash.js
38
lodash.js
@@ -80,6 +80,7 @@
|
||||
regexpTag = '[object RegExp]',
|
||||
setTag = '[object Set]',
|
||||
stringTag = '[object String]',
|
||||
symbolTag = '[object Symbol]',
|
||||
weakMapTag = '[object WeakMap]';
|
||||
|
||||
var arrayBufferTag = '[object ArrayBuffer]',
|
||||
@@ -253,8 +254,9 @@
|
||||
cloneableTags[mapTag] = cloneableTags[numberTag] =
|
||||
cloneableTags[objectTag] = cloneableTags[regexpTag] =
|
||||
cloneableTags[setTag] = cloneableTags[stringTag] =
|
||||
cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =
|
||||
cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;
|
||||
cloneableTags[symbolTag] = cloneableTags[uint8Tag] =
|
||||
cloneableTags[uint8ClampedTag] = cloneableTags[uint16Tag] =
|
||||
cloneableTags[uint32Tag] = true;
|
||||
cloneableTags[errorTag] = cloneableTags[funcTag] =
|
||||
cloneableTags[weakMapTag] = false;
|
||||
|
||||
@@ -1458,6 +1460,9 @@
|
||||
var mapCtorString = Map ? fnToString.call(Map) : '',
|
||||
setCtorString = Set ? fnToString.call(Set) : '';
|
||||
|
||||
/** Used to convert symbols to strings. */
|
||||
var symbolToString = Symbol ? Symbol.prototype.toString : undefined;
|
||||
|
||||
/** Used to lookup unminified function names. */
|
||||
var realNames = {};
|
||||
|
||||
@@ -2772,7 +2777,10 @@
|
||||
if (value === other) {
|
||||
return true;
|
||||
}
|
||||
if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) {
|
||||
if (value == null || other == null || (
|
||||
!(typeof value == 'symbol' || isObject(value)) &&
|
||||
!(typeof other == 'symbol' || isObjectLike(other))
|
||||
)) {
|
||||
return value !== value && other !== other;
|
||||
}
|
||||
return baseIsEqualDeep(value, other, baseIsEqual, customizer, bitmask, stack);
|
||||
@@ -3750,6 +3758,20 @@
|
||||
return arrayReduce(setToArray(set), addSetEntry, new Ctor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a clone of `symbol`.
|
||||
*
|
||||
* @private
|
||||
* @param {Object} symbol The symbol to clone.
|
||||
* @returns {Object} Returns the cloned symbol.
|
||||
*/
|
||||
function cloneSymbol(symbol) {
|
||||
var Ctor = symbol.constructor,
|
||||
result = Ctor(symbolToString.call(symbol).slice(7, -1));
|
||||
|
||||
return typeof symbol == 'object' ? Object(result) : result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a clone of `typedArray`.
|
||||
*
|
||||
@@ -4519,6 +4541,9 @@
|
||||
// Recursively compare objects (susceptible to call stack limits).
|
||||
return (isPartial || object.size == other.size) &&
|
||||
equalFunc(convert(object), convert(other), customizer, bitmask | UNORDERED_COMPARE_FLAG);
|
||||
|
||||
case symbolTag:
|
||||
return symbolToString.call(object) == symbolToString.call(other);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -4831,11 +4856,14 @@
|
||||
case stringTag:
|
||||
return new Ctor(object);
|
||||
|
||||
case regexpTag:
|
||||
return cloneRegExp(object);
|
||||
|
||||
case setTag:
|
||||
return cloneSet(object);
|
||||
|
||||
case regexpTag:
|
||||
return cloneRegExp(object);
|
||||
case symbolTag:
|
||||
return cloneSymbol(object);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
61
test/test.js
61
test/test.js
@@ -2199,6 +2199,9 @@
|
||||
set.add(1);
|
||||
set.add(2);
|
||||
}
|
||||
if (Symbol) {
|
||||
var symbol = Symbol('a');
|
||||
}
|
||||
var objects = {
|
||||
'`arguments` objects': arguments,
|
||||
'arrays': ['a', ''],
|
||||
@@ -2217,6 +2220,7 @@
|
||||
'sets': set,
|
||||
'strings': 'a',
|
||||
'string objects': Object('a'),
|
||||
'symbols': symbol,
|
||||
'undefined values': undefined
|
||||
};
|
||||
|
||||
@@ -2309,12 +2313,14 @@
|
||||
QUnit.test('`_.' + methodName + '` should clone ' + key, function(assert) {
|
||||
assert.expect(2);
|
||||
|
||||
var isEqual = (key == 'maps' || key == 'sets') ? _.isEqual : lodashStable,
|
||||
var useUnstable = /^(?:maps|sets|symbols)$/.test(key),
|
||||
isEqual = useUnstable ? _.isEqual : lodashStable.isEqual,
|
||||
isObject = useUnstable ? _.isObject : lodashStable.isObject,
|
||||
actual = func(object);
|
||||
|
||||
assert.ok(isEqual(actual, object));
|
||||
|
||||
if (lodashStable.isObject(object)) {
|
||||
if (isObject(object)) {
|
||||
assert.notStrictEqual(actual, object);
|
||||
} else {
|
||||
assert.strictEqual(actual, object);
|
||||
@@ -2358,6 +2364,22 @@
|
||||
assert.strictEqual(actual.lastIndex, 3);
|
||||
});
|
||||
|
||||
QUnit.test('`_.' + methodName + '` should clone symbol objects', function(assert) {
|
||||
assert.expect(3);
|
||||
|
||||
if (Symbol) {
|
||||
var object = Object(symbol),
|
||||
actual = func(object);
|
||||
|
||||
assert.strictEqual(typeof actual, 'object');
|
||||
assert.strictEqual(typeof actual.valueOf(), 'symbol');
|
||||
assert.notStrictEqual(actual, object);
|
||||
}
|
||||
else {
|
||||
skipTest(assert, 3);
|
||||
}
|
||||
});
|
||||
|
||||
QUnit.test('`_.' + methodName + '` should not error on DOM elements', function(assert) {
|
||||
assert.expect(1);
|
||||
|
||||
@@ -8113,6 +8135,30 @@
|
||||
}
|
||||
});
|
||||
|
||||
QUnit.test('should compare symbols', function(assert) {
|
||||
assert.expect(4);
|
||||
|
||||
if (Symbol) {
|
||||
var symbol1 = Symbol('a'),
|
||||
symbol2 = Symbol('b');
|
||||
|
||||
assert.strictEqual(_.isEqual(symbol1, symbol2), false);
|
||||
|
||||
symbol2 = Symbol('a');
|
||||
assert.strictEqual(_.isEqual(symbol1, symbol2), true);
|
||||
|
||||
symbol1 = Symbol(undefined);
|
||||
symbol2 = Symbol('');
|
||||
assert.strictEqual(_.isEqual(symbol1, symbol2), true);
|
||||
|
||||
symbol1 = Symbol(null);
|
||||
assert.strictEqual(_.isEqual(symbol1, symbol2), false);
|
||||
}
|
||||
else {
|
||||
skipTest(assert, 4);
|
||||
}
|
||||
});
|
||||
|
||||
QUnit.test('should compare typed arrays', function(assert) {
|
||||
assert.expect(1);
|
||||
|
||||
@@ -9452,7 +9498,7 @@
|
||||
var args = arguments;
|
||||
|
||||
QUnit.test('should return `true` for objects', function(assert) {
|
||||
assert.expect(12);
|
||||
assert.expect(13);
|
||||
|
||||
assert.strictEqual(_.isObject(args), true);
|
||||
assert.strictEqual(_.isObject([1, 2, 3]), true);
|
||||
@@ -9468,7 +9514,14 @@
|
||||
|
||||
if (document) {
|
||||
assert.strictEqual(_.isObject(body), true);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
skipTest(assert);
|
||||
}
|
||||
if (Symbol) {
|
||||
assert.strictEqual(_.isObject(Object(Symbol())), true);
|
||||
}
|
||||
else {
|
||||
skipTest(assert);
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user