Skip to content

Commit

Permalink
[New] support enumerable Symbol properties
Browse files Browse the repository at this point in the history
  • Loading branch information
Americas authored and ljharb committed Dec 20, 2023
1 parent 22952cf commit 7d659e7
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 4 deletions.
27 changes: 23 additions & 4 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,25 @@ var objectKeys = Object.keys || function keys(obj) {
return res;
};

var propertyIsEnumerable = Object.prototype.propertyIsEnumerable;
var getOwnPropertySymbols = Object.getOwnPropertySymbols; // eslint-disable-line id-length

// TODO: use reflect.ownkeys and filter out non-enumerables
function ownEnumerableKeys(obj) {
var res = objectKeys(obj);

// Include enumerable symbol properties.
if (getOwnPropertySymbols) {
var symbols = getOwnPropertySymbols(obj);
for (var i = 0; i < symbols.length; i++) {
if (propertyIsEnumerable.call(obj, symbols[i])) {
res.push(symbols[i]);
}
}
}
return res;
}

// TODO: use object.hasown
var hasOwnProperty = Object.prototype.hasOwnProperty || function (obj, key) {
return key in obj;
Expand Down Expand Up @@ -62,7 +81,7 @@ function copy(src) {
dst = new T();
}

forEach(objectKeys(src), function (key) {
forEach(ownEnumerableKeys(src), function (key) {
dst[key] = src[key];
});
return dst;
Expand Down Expand Up @@ -124,7 +143,7 @@ function walk(root, cb, immutable) {
function updateState() {
if (typeof state.node === 'object' && state.node !== null) {
if (!state.keys || state.node_ !== state.node) {
state.keys = objectKeys(state.node);
state.keys = ownEnumerableKeys(state.node);
}

state.isLeaf = state.keys.length === 0;
Expand Down Expand Up @@ -281,7 +300,7 @@ Traverse.prototype.clone = function () {
parents.push(src);
nodes.push(dst);

forEach(objectKeys(src), function (key) {
forEach(ownEnumerableKeys(src), function (key) {
dst[key] = clone(src[key]);
});

Expand All @@ -300,7 +319,7 @@ function traverse(obj) {
}

// TODO: replace with object.assign?
forEach(objectKeys(Traverse.prototype), function (key) {
forEach(ownEnumerableKeys(Traverse.prototype), function (key) {
traverse[key] = function (obj) {
var args = [].slice.call(arguments, 1);
var t = new Traverse(obj);
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"@ljharb/eslint-config": "^21.1.0",
"aud": "^2.0.4",
"auto-changelog": "^2.4.0",
"es-value-fixtures": "^1.4.2",
"eslint": "=8.8.0",
"in-publish": "^2.0.1",
"npmignore": "^0.3.1",
Expand Down
22 changes: 22 additions & 0 deletions test/has.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use strict';

var test = require('tape');
var v = require('es-value-fixtures');
var traverse = require('../');

test('has', function (t) {
Expand All @@ -13,5 +14,26 @@ test('has', function (t) {
t.equal(traverse(obj).has(['a']), true);
t.equal(traverse(obj).has(['a', 2]), false);

t.test('symbols', { skip: !v.hasSymbols }, function (st) {
/* eslint no-restricted-properties: 1 */
var globalSymbol = Symbol.for('d');
var localSymbol = Symbol('e');

obj[globalSymbol] = {};
obj[globalSymbol][localSymbol] = 7;
obj[localSymbol] = 8;

st.equal(traverse(obj).has([globalSymbol]), true);
st.equal(traverse(obj).has([globalSymbol, globalSymbol]), false);
st.equal(traverse(obj).has([globalSymbol, localSymbol]), true);
st.equal(traverse(obj).has([localSymbol]), true);
st.equal(traverse(obj).has([localSymbol]), true);
st.equal(traverse(obj).has([Symbol('e')]), false);
st.equal(traverse(obj).has([Symbol.for('d')]), true);
st.equal(traverse(obj).has([Symbol.for('e')]), false);

st.end();
});

t.end();
});

0 comments on commit 7d659e7

Please sign in to comment.