mirror of
https://github.com/ONLYOFFICE/web-apps.git
synced 2026-04-07 14:06:16 +08:00
1421 lines
50 KiB
HTML
1421 lines
50 KiB
HTML
|
||
<!DOCTYPE html>
|
||
|
||
<html>
|
||
<head>
|
||
<title>isEqual.js</title>
|
||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||
<meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
|
||
<link rel="stylesheet" media="all" href="../docco.css" />
|
||
</head>
|
||
<body>
|
||
<div id="container">
|
||
<div id="background"></div>
|
||
|
||
<ul id="jump_to">
|
||
<li>
|
||
<a class="large" href="javascript:void(0);">Jump To …</a>
|
||
<a class="small" href="javascript:void(0);">+</a>
|
||
<div id="jump_wrapper">
|
||
<div id="jump_page_wrapper">
|
||
<div id="jump_page">
|
||
|
||
|
||
<a class="source" href="_baseCreate.html">
|
||
modules/_baseCreate.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="_baseIteratee.html">
|
||
modules/_baseIteratee.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="_cb.html">
|
||
modules/_cb.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="_chainResult.html">
|
||
modules/_chainResult.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="_collectNonEnumProps.html">
|
||
modules/_collectNonEnumProps.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="_createAssigner.html">
|
||
modules/_createAssigner.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="_createEscaper.html">
|
||
modules/_createEscaper.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="_createIndexFinder.html">
|
||
modules/_createIndexFinder.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="_createPredicateIndexFinder.html">
|
||
modules/_createPredicateIndexFinder.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="_createReduce.html">
|
||
modules/_createReduce.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="_createSizePropertyCheck.html">
|
||
modules/_createSizePropertyCheck.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="_deepGet.html">
|
||
modules/_deepGet.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="_escapeMap.html">
|
||
modules/_escapeMap.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="_executeBound.html">
|
||
modules/_executeBound.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="_flatten.html">
|
||
modules/_flatten.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="_getByteLength.html">
|
||
modules/_getByteLength.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="_getLength.html">
|
||
modules/_getLength.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="_group.html">
|
||
modules/_group.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="_has.html">
|
||
modules/_has.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="_hasObjectTag.html">
|
||
modules/_hasObjectTag.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="_isArrayLike.html">
|
||
modules/_isArrayLike.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="_isBufferLike.html">
|
||
modules/_isBufferLike.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="_keyInObj.html">
|
||
modules/_keyInObj.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="_methodFingerprint.html">
|
||
modules/_methodFingerprint.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="_optimizeCb.html">
|
||
modules/_optimizeCb.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="_setup.html">
|
||
modules/_setup.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="_shallowProperty.html">
|
||
modules/_shallowProperty.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="_stringTagBug.html">
|
||
modules/_stringTagBug.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="_tagTester.html">
|
||
modules/_tagTester.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="_toBufferView.html">
|
||
modules/_toBufferView.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="_toPath.html">
|
||
modules/_toPath.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="_unescapeMap.html">
|
||
modules/_unescapeMap.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="after.html">
|
||
modules/after.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="allKeys.html">
|
||
modules/allKeys.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="before.html">
|
||
modules/before.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="bind.html">
|
||
modules/bind.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="bindAll.html">
|
||
modules/bindAll.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="chain.html">
|
||
modules/chain.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="chunk.html">
|
||
modules/chunk.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="clone.html">
|
||
modules/clone.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="compact.html">
|
||
modules/compact.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="compose.html">
|
||
modules/compose.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="constant.html">
|
||
modules/constant.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="contains.html">
|
||
modules/contains.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="countBy.html">
|
||
modules/countBy.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="create.html">
|
||
modules/create.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="debounce.html">
|
||
modules/debounce.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="defaults.html">
|
||
modules/defaults.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="defer.html">
|
||
modules/defer.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="delay.html">
|
||
modules/delay.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="difference.html">
|
||
modules/difference.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="each.html">
|
||
modules/each.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="escape.html">
|
||
modules/escape.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="every.html">
|
||
modules/every.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="extend.html">
|
||
modules/extend.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="extendOwn.html">
|
||
modules/extendOwn.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="filter.html">
|
||
modules/filter.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="find.html">
|
||
modules/find.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="findIndex.html">
|
||
modules/findIndex.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="findKey.html">
|
||
modules/findKey.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="findLastIndex.html">
|
||
modules/findLastIndex.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="findWhere.html">
|
||
modules/findWhere.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="first.html">
|
||
modules/first.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="flatten.html">
|
||
modules/flatten.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="functions.html">
|
||
modules/functions.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="get.html">
|
||
modules/get.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="groupBy.html">
|
||
modules/groupBy.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="has.html">
|
||
modules/has.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="identity.html">
|
||
modules/identity.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="index-all.html">
|
||
modules/index-all.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="index-default.html">
|
||
modules/index-default.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="index.html">
|
||
modules/index.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="indexBy.html">
|
||
modules/indexBy.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="indexOf.html">
|
||
modules/indexOf.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="initial.html">
|
||
modules/initial.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="intersection.html">
|
||
modules/intersection.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="invert.html">
|
||
modules/invert.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="invoke.html">
|
||
modules/invoke.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="isArguments.html">
|
||
modules/isArguments.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="isArray.html">
|
||
modules/isArray.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="isArrayBuffer.html">
|
||
modules/isArrayBuffer.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="isBoolean.html">
|
||
modules/isBoolean.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="isDataView.html">
|
||
modules/isDataView.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="isDate.html">
|
||
modules/isDate.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="isElement.html">
|
||
modules/isElement.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="isEmpty.html">
|
||
modules/isEmpty.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="isEqual.html">
|
||
modules/isEqual.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="isError.html">
|
||
modules/isError.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="isFinite.html">
|
||
modules/isFinite.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="isFunction.html">
|
||
modules/isFunction.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="isMap.html">
|
||
modules/isMap.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="isMatch.html">
|
||
modules/isMatch.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="isNaN.html">
|
||
modules/isNaN.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="isNull.html">
|
||
modules/isNull.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="isNumber.html">
|
||
modules/isNumber.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="isObject.html">
|
||
modules/isObject.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="isRegExp.html">
|
||
modules/isRegExp.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="isSet.html">
|
||
modules/isSet.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="isString.html">
|
||
modules/isString.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="isSymbol.html">
|
||
modules/isSymbol.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="isTypedArray.html">
|
||
modules/isTypedArray.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="isUndefined.html">
|
||
modules/isUndefined.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="isWeakMap.html">
|
||
modules/isWeakMap.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="isWeakSet.html">
|
||
modules/isWeakSet.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="iteratee.html">
|
||
modules/iteratee.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="keys.html">
|
||
modules/keys.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="last.html">
|
||
modules/last.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="lastIndexOf.html">
|
||
modules/lastIndexOf.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="map.html">
|
||
modules/map.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="mapObject.html">
|
||
modules/mapObject.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="matcher.html">
|
||
modules/matcher.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="max.html">
|
||
modules/max.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="memoize.html">
|
||
modules/memoize.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="min.html">
|
||
modules/min.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="mixin.html">
|
||
modules/mixin.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="negate.html">
|
||
modules/negate.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="noop.html">
|
||
modules/noop.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="now.html">
|
||
modules/now.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="object.html">
|
||
modules/object.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="omit.html">
|
||
modules/omit.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="once.html">
|
||
modules/once.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="pairs.html">
|
||
modules/pairs.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="partial.html">
|
||
modules/partial.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="partition.html">
|
||
modules/partition.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="pick.html">
|
||
modules/pick.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="pluck.html">
|
||
modules/pluck.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="property.html">
|
||
modules/property.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="propertyOf.html">
|
||
modules/propertyOf.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="random.html">
|
||
modules/random.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="range.html">
|
||
modules/range.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="reduce.html">
|
||
modules/reduce.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="reduceRight.html">
|
||
modules/reduceRight.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="reject.html">
|
||
modules/reject.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="rest.html">
|
||
modules/rest.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="restArguments.html">
|
||
modules/restArguments.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="result.html">
|
||
modules/result.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="sample.html">
|
||
modules/sample.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="shuffle.html">
|
||
modules/shuffle.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="size.html">
|
||
modules/size.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="some.html">
|
||
modules/some.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="sortBy.html">
|
||
modules/sortBy.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="sortedIndex.html">
|
||
modules/sortedIndex.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="tap.html">
|
||
modules/tap.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="template.html">
|
||
modules/template.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="templateSettings.html">
|
||
modules/templateSettings.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="throttle.html">
|
||
modules/throttle.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="times.html">
|
||
modules/times.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="toArray.html">
|
||
modules/toArray.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="toPath.html">
|
||
modules/toPath.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="underscore-array-methods.html">
|
||
modules/underscore-array-methods.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="underscore.html">
|
||
modules/underscore.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="unescape.html">
|
||
modules/unescape.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="union.html">
|
||
modules/union.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="uniq.html">
|
||
modules/uniq.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="uniqueId.html">
|
||
modules/uniqueId.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="unzip.html">
|
||
modules/unzip.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="values.html">
|
||
modules/values.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="where.html">
|
||
modules/where.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="without.html">
|
||
modules/without.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="wrap.html">
|
||
modules/wrap.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="zip.html">
|
||
modules/zip.js
|
||
</a>
|
||
|
||
</div>
|
||
</div>
|
||
</li>
|
||
</ul>
|
||
|
||
<ul class="sections">
|
||
|
||
<li id="title">
|
||
<div class="annotation">
|
||
<h1>isEqual.js</h1>
|
||
</div>
|
||
</li>
|
||
|
||
|
||
|
||
<li id="section-1">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-1">¶</a>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre><span class="hljs-keyword">import</span> _ <span class="hljs-keyword">from</span> <span class="hljs-string">'./underscore.js'</span>;
|
||
<span class="hljs-keyword">import</span> { toString, <span class="hljs-title class_">SymbolProto</span> } <span class="hljs-keyword">from</span> <span class="hljs-string">'./_setup.js'</span>;
|
||
<span class="hljs-keyword">import</span> getByteLength <span class="hljs-keyword">from</span> <span class="hljs-string">'./_getByteLength.js'</span>;
|
||
<span class="hljs-keyword">import</span> isTypedArray <span class="hljs-keyword">from</span> <span class="hljs-string">'./isTypedArray.js'</span>;
|
||
<span class="hljs-keyword">import</span> isFunction <span class="hljs-keyword">from</span> <span class="hljs-string">'./isFunction.js'</span>;
|
||
<span class="hljs-keyword">import</span> { hasStringTagBug } <span class="hljs-keyword">from</span> <span class="hljs-string">'./_stringTagBug.js'</span>;
|
||
<span class="hljs-keyword">import</span> isDataView <span class="hljs-keyword">from</span> <span class="hljs-string">'./isDataView.js'</span>;
|
||
<span class="hljs-keyword">import</span> keys <span class="hljs-keyword">from</span> <span class="hljs-string">'./keys.js'</span>;
|
||
<span class="hljs-keyword">import</span> has <span class="hljs-keyword">from</span> <span class="hljs-string">'./_has.js'</span>;
|
||
<span class="hljs-keyword">import</span> toBufferView <span class="hljs-keyword">from</span> <span class="hljs-string">'./_toBufferView.js'</span>;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-2">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-2">¶</a>
|
||
</div>
|
||
<p>We use this string twice, so give it a name for minification.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre><span class="hljs-keyword">var</span> tagDataView = <span class="hljs-string">'[object DataView]'</span>;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-3">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-3">¶</a>
|
||
</div>
|
||
<p>Internal recursive comparison function for <code>_.isEqual</code>.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre><span class="hljs-keyword">function</span> <span class="hljs-title function_">eq</span>(<span class="hljs-params">a, b, aStack, bStack</span>) {</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-4">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-4">¶</a>
|
||
</div>
|
||
<p>Identical objects are equal. <code>0 === -0</code>, but they aren’t identical.
|
||
See the <a href="https://wiki.ecmascript.org/doku.php?id=harmony:egal">Harmony <code>egal</code> proposal</a>.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (a === b) <span class="hljs-keyword">return</span> a !== <span class="hljs-number">0</span> || <span class="hljs-number">1</span> / a === <span class="hljs-number">1</span> / b;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-5">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-5">¶</a>
|
||
</div>
|
||
<p><code>null</code> or <code>undefined</code> only equal to itself (strict comparison).</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (a == <span class="hljs-literal">null</span> || b == <span class="hljs-literal">null</span>) <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-6">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-6">¶</a>
|
||
</div>
|
||
<p><code>NaN</code>s are equivalent, but non-reflexive.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (a !== a) <span class="hljs-keyword">return</span> b !== b;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-7">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-7">¶</a>
|
||
</div>
|
||
<p>Exhaust primitive checks</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> type = <span class="hljs-keyword">typeof</span> a;
|
||
<span class="hljs-keyword">if</span> (type !== <span class="hljs-string">'function'</span> && type !== <span class="hljs-string">'object'</span> && <span class="hljs-keyword">typeof</span> b != <span class="hljs-string">'object'</span>) <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
|
||
<span class="hljs-keyword">return</span> <span class="hljs-title function_">deepEq</span>(a, b, aStack, bStack);
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-8">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-8">¶</a>
|
||
</div>
|
||
<p>Internal recursive comparison function for <code>_.isEqual</code>.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre><span class="hljs-keyword">function</span> <span class="hljs-title function_">deepEq</span>(<span class="hljs-params">a, b, aStack, bStack</span>) {</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-9">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-9">¶</a>
|
||
</div>
|
||
<p>Unwrap any wrapped objects.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (a <span class="hljs-keyword">instanceof</span> _) a = a.<span class="hljs-property">_wrapped</span>;
|
||
<span class="hljs-keyword">if</span> (b <span class="hljs-keyword">instanceof</span> _) b = b.<span class="hljs-property">_wrapped</span>;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-10">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-10">¶</a>
|
||
</div>
|
||
<p>Compare <code>[[Class]]</code> names.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> className = toString.<span class="hljs-title function_">call</span>(a);
|
||
<span class="hljs-keyword">if</span> (className !== toString.<span class="hljs-title function_">call</span>(b)) <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-11">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-11">¶</a>
|
||
</div>
|
||
<p>Work around a bug in IE 10 - Edge 13.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (hasStringTagBug && className == <span class="hljs-string">'[object Object]'</span> && <span class="hljs-title function_">isDataView</span>(a)) {
|
||
<span class="hljs-keyword">if</span> (!<span class="hljs-title function_">isDataView</span>(b)) <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
|
||
className = tagDataView;
|
||
}
|
||
<span class="hljs-keyword">switch</span> (className) {</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-12">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-12">¶</a>
|
||
</div>
|
||
<p>These types are compared by value.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> <span class="hljs-string">'[object RegExp]'</span>:</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-13">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-13">¶</a>
|
||
</div>
|
||
<p>RegExps are coerced to strings for comparison (Note: ‘’ + /a/i === ‘/a/i’)</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">case</span> <span class="hljs-string">'[object String]'</span>:</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-14">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-14">¶</a>
|
||
</div>
|
||
<p>Primitives and their corresponding object wrappers are equivalent; thus, <code>"5"</code> is
|
||
equivalent to <code>new String("5")</code>.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> <span class="hljs-string">''</span> + a === <span class="hljs-string">''</span> + b;
|
||
<span class="hljs-keyword">case</span> <span class="hljs-string">'[object Number]'</span>:</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-15">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-15">¶</a>
|
||
</div>
|
||
<p><code>NaN</code>s are equivalent, but non-reflexive.
|
||
Object(NaN) is equivalent to NaN.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (+a !== +a) <span class="hljs-keyword">return</span> +b !== +b;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-16">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-16">¶</a>
|
||
</div>
|
||
<p>An <code>egal</code> comparison is performed for other numeric values.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> +a === <span class="hljs-number">0</span> ? <span class="hljs-number">1</span> / +a === <span class="hljs-number">1</span> / b : +a === +b;
|
||
<span class="hljs-keyword">case</span> <span class="hljs-string">'[object Date]'</span>:
|
||
<span class="hljs-keyword">case</span> <span class="hljs-string">'[object Boolean]'</span>:</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-17">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-17">¶</a>
|
||
</div>
|
||
<p>Coerce dates and booleans to numeric primitive values. Dates are compared by their
|
||
millisecond representations. Note that invalid dates with millisecond representations
|
||
of <code>NaN</code> are not equivalent.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> +a === +b;
|
||
<span class="hljs-keyword">case</span> <span class="hljs-string">'[object Symbol]'</span>:
|
||
<span class="hljs-keyword">return</span> <span class="hljs-title class_">SymbolProto</span>.<span class="hljs-property">valueOf</span>.<span class="hljs-title function_">call</span>(a) === <span class="hljs-title class_">SymbolProto</span>.<span class="hljs-property">valueOf</span>.<span class="hljs-title function_">call</span>(b);
|
||
<span class="hljs-keyword">case</span> <span class="hljs-string">'[object ArrayBuffer]'</span>:
|
||
<span class="hljs-keyword">case</span> <span class="hljs-attr">tagDataView</span>:</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-18">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-18">¶</a>
|
||
</div>
|
||
<p>Coerce to typed array so we can fall through.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> <span class="hljs-title function_">deepEq</span>(<span class="hljs-title function_">toBufferView</span>(a), <span class="hljs-title function_">toBufferView</span>(b), aStack, bStack);
|
||
}
|
||
|
||
<span class="hljs-keyword">var</span> areArrays = className === <span class="hljs-string">'[object Array]'</span>;
|
||
<span class="hljs-keyword">if</span> (!areArrays && <span class="hljs-title function_">isTypedArray</span>(a)) {
|
||
<span class="hljs-keyword">var</span> byteLength = <span class="hljs-title function_">getByteLength</span>(a);
|
||
<span class="hljs-keyword">if</span> (byteLength !== <span class="hljs-title function_">getByteLength</span>(b)) <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
|
||
<span class="hljs-keyword">if</span> (a.<span class="hljs-property">buffer</span> === b.<span class="hljs-property">buffer</span> && a.<span class="hljs-property">byteOffset</span> === b.<span class="hljs-property">byteOffset</span>) <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
|
||
areArrays = <span class="hljs-literal">true</span>;
|
||
}
|
||
<span class="hljs-keyword">if</span> (!areArrays) {
|
||
<span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> a != <span class="hljs-string">'object'</span> || <span class="hljs-keyword">typeof</span> b != <span class="hljs-string">'object'</span>) <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-19">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-19">¶</a>
|
||
</div>
|
||
<p>Objects with different constructors are not equivalent, but <code>Object</code>s or <code>Array</code>s
|
||
from different frames are.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> aCtor = a.<span class="hljs-property">constructor</span>, bCtor = b.<span class="hljs-property">constructor</span>;
|
||
<span class="hljs-keyword">if</span> (aCtor !== bCtor && !(<span class="hljs-title function_">isFunction</span>(aCtor) && aCtor <span class="hljs-keyword">instanceof</span> aCtor &&
|
||
<span class="hljs-title function_">isFunction</span>(bCtor) && bCtor <span class="hljs-keyword">instanceof</span> bCtor)
|
||
&& (<span class="hljs-string">'constructor'</span> <span class="hljs-keyword">in</span> a && <span class="hljs-string">'constructor'</span> <span class="hljs-keyword">in</span> b)) {
|
||
<span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
|
||
}
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-20">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-20">¶</a>
|
||
</div>
|
||
<p>Assume equality for cyclic structures. The algorithm for detecting cyclic
|
||
structures is adapted from ES 5.1 section 15.12.3, abstract operation <code>JO</code>.</p>
|
||
|
||
</div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-21">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-21">¶</a>
|
||
</div>
|
||
<p>Initializing stack of traversed objects.
|
||
It’s done here since we only need them for objects and arrays comparison.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> aStack = aStack || [];
|
||
bStack = bStack || [];
|
||
<span class="hljs-keyword">var</span> length = aStack.<span class="hljs-property">length</span>;
|
||
<span class="hljs-keyword">while</span> (length--) {</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-22">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-22">¶</a>
|
||
</div>
|
||
<p>Linear search. Performance is inversely proportional to the number of
|
||
unique nested structures.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (aStack[length] === a) <span class="hljs-keyword">return</span> bStack[length] === b;
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-23">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-23">¶</a>
|
||
</div>
|
||
<p>Add the first object to the stack of traversed objects.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> aStack.<span class="hljs-title function_">push</span>(a);
|
||
bStack.<span class="hljs-title function_">push</span>(b);</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-24">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-24">¶</a>
|
||
</div>
|
||
<p>Recursively compare objects and arrays.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (areArrays) {</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-25">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-25">¶</a>
|
||
</div>
|
||
<p>Compare array lengths to determine if a deep comparison is necessary.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> length = a.<span class="hljs-property">length</span>;
|
||
<span class="hljs-keyword">if</span> (length !== b.<span class="hljs-property">length</span>) <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-26">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-26">¶</a>
|
||
</div>
|
||
<p>Deep compare the contents, ignoring non-numeric properties.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">while</span> (length--) {
|
||
<span class="hljs-keyword">if</span> (!<span class="hljs-title function_">eq</span>(a[length], b[length], aStack, bStack)) <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
|
||
}
|
||
} <span class="hljs-keyword">else</span> {</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-27">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-27">¶</a>
|
||
</div>
|
||
<p>Deep compare objects.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> _keys = <span class="hljs-title function_">keys</span>(a), key;
|
||
length = _keys.<span class="hljs-property">length</span>;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-28">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-28">¶</a>
|
||
</div>
|
||
<p>Ensure that both objects contain the same number of properties before comparing deep equality.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (<span class="hljs-title function_">keys</span>(b).<span class="hljs-property">length</span> !== length) <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
|
||
<span class="hljs-keyword">while</span> (length--) {</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-29">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-29">¶</a>
|
||
</div>
|
||
<p>Deep compare each member</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> key = _keys[length];
|
||
<span class="hljs-keyword">if</span> (!(<span class="hljs-title function_">has</span>(b, key) && <span class="hljs-title function_">eq</span>(a[key], b[key], aStack, bStack))) <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
|
||
}
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-30">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-30">¶</a>
|
||
</div>
|
||
<p>Remove the first object from the stack of traversed objects.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> aStack.<span class="hljs-title function_">pop</span>();
|
||
bStack.<span class="hljs-title function_">pop</span>();
|
||
<span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-31">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-31">¶</a>
|
||
</div>
|
||
<p>Perform a deep comparison to check if two objects are equal.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">isEqual</span>(<span class="hljs-params">a, b</span>) {
|
||
<span class="hljs-keyword">return</span> <span class="hljs-title function_">eq</span>(a, b);
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</div>
|
||
|
||
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
|
||
<script>
|
||
// We run a script at page load to inject the links after the fact.
|
||
// It would be more elegant to do this at page generation time, but
|
||
// unfortunately the docco infrastructure doesn't support this very well.
|
||
// Highlighted code is passed along as an unparsed HTML string, which would
|
||
// make this very tricky. In the script below, we exploit the fact that the
|
||
// HTML has already been parsed by the browser.
|
||
(function() {
|
||
// Define a regex for stripping the .html extension from anchor hrefs.
|
||
var extPattern = /\.html$/;
|
||
// Collect all module paths that we have an HTML page for.
|
||
var moduleMap = {};
|
||
$('#jump_page a.source').each(function() {
|
||
// Fortunately, translating anchor hrefs to ES module paths is easy,
|
||
// because both systems work relative to the current file by default.
|
||
var href = $(this).attr('href');
|
||
var path = href.replace(extPattern, '').split('/');
|
||
if (path[0] !== '..') path.unshift('.');
|
||
var normPath = path.join('/');
|
||
// Support both paths with and without extension.
|
||
moduleMap[normPath] = moduleMap[normPath + '.js'] = href;
|
||
});
|
||
// Find all 'from' keywords followed by a string (ES6 import statements).
|
||
$('.hljs-keyword').filter(function() {
|
||
var text = $(this).text();
|
||
return text === 'from' || text === 'import';
|
||
}).next('.hljs-string').each(function() {
|
||
// Finally, for each of these strings, replace it by a link if we have
|
||
// a matching HTML page.
|
||
var text = $(this).text();
|
||
var quote = text[0];
|
||
var path = text.slice(1, -1);
|
||
var matchingDoc = moduleMap[path];
|
||
if (!matchingDoc) return;
|
||
$(this).html(
|
||
quote + '<a href="' + matchingDoc + '">' + path + '</a>' + quote
|
||
);
|
||
});
|
||
}());
|
||
</script>
|
||
|
||
</body>
|
||
</html>
|