Skip to content

Instantly share code, notes, and snippets.

@petsel
Last active June 6, 2020 09:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save petsel/466e58633ea5e0a911d8d00fdde1f9ae to your computer and use it in GitHub Desktop.
Save petsel/466e58633ea5e0a911d8d00fdde1f9ae to your computer and use it in GitHub Desktop.
function isBooleanValue(type) {
return (typeof type === 'boolean');
}
function isNumberValue(type) {
return (typeof type === 'number');
}
function isStringValue(type) {
return (typeof type === 'string');
}
function isSymbol(type) {
return (typeof type === 'symbol');
}
function isPrimitive(type) {
return (
isBooleanValue(type)
|| isNumberValue(type)
|| isStringValue(type)
|| isSymbol(type)
);
}
function isObject(type) {
return (!!type && (typeof type === 'object'));
}
function isFunction(type) {
const functionType = 'function';
return (
(typeof type === functionType)
&& (typeof type.call === functionType)
&& (typeof type.apply === functionType)
);
}
/**
* - recursively collect a list of a type’s accessible keys
* that also might be inherited, but that are neither keys
* of `Object.prototype` nor keys of `Function.prototype`.
*/
function getAllAccessiblePropertyNames(type, keyList) {
// default return value.
keyList = (keyList || []);
// accept primitive data types as well.
if (isPrimitive(type)) {
type = Object(type);
}
// undefined and null value are kept out.
if (isObject(type)) {
keyList = keyList.concat(
Object.keys(type)
).concat(
Object.getOwnPropertyNames(type)
);
const protoType = (isFunction(type.constructor) && type.constructor.prototype);
if (protoType && (protoType !== Object.prototype)) {
if (protoType === protoType.constructor.prototype) {
keyList = keyList.concat(
Object.keys(protoType)
).concat(
Object.getOwnPropertyNames(protoType)
);
} else {
keyList = getAllAccessiblePropertyNames(protoType, keyList);
}
}
const proto = type.__proto__;
if ((isObject(proto) || isFunction(proto)) && (proto !== Object.prototype)) {
if (proto === proto.__proto__) {
keyList = keyList.concat(
Object.keys(proto)
).concat(
Object.getOwnPropertyNames(proto)
);
} else {
keyList = getAllAccessiblePropertyNames(proto, keyList);
}
}
}
return [...(new Set(keyList))].filter(key => !(/^\d+$/).test(key));
}
console.log(getAllAccessiblePropertyNames());
console.log(getAllAccessiblePropertyNames(null));
console.log(getAllAccessiblePropertyNames(void null));
console.log(getAllAccessiblePropertyNames({}.__proto__));
console.log(getAllAccessiblePropertyNames(Function.prototype));
console.log(getAllAccessiblePropertyNames((function () {}).__proto__));
console.log(getAllAccessiblePropertyNames([].__proto__));
console.log(getAllAccessiblePropertyNames(["foo", "bar", "baz"]));
console.log(getAllAccessiblePropertyNames(RegExp.prototype));
console.log(getAllAccessiblePropertyNames(/\s+/));
console.log(getAllAccessiblePropertyNames(new Date));
console.log(getAllAccessiblePropertyNames(Date.prototype));
console.log(getAllAccessiblePropertyNames(JSON));
console.log(getAllAccessiblePropertyNames(Math));
console.log(getAllAccessiblePropertyNames(Date));
console.log(getAllAccessiblePropertyNames(RegExp));
console.log(getAllAccessiblePropertyNames(Symbol('foo')));
console.log(getAllAccessiblePropertyNames('bar'));
console.log(getAllAccessiblePropertyNames(1024));
console.log(getAllAccessiblePropertyNames(true));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment