I have a simple browser feature checking function called canUse() which can check for a variety of things, but checking for private class feature (i.e. #) support ended up like this:
canUse('(new (class { #private = 0; getPrivate() { return this.#private; } })).getPrivate();', 'eval')
Is there a faster way to check for this feature without using try...catch, eval(), and user agent sniffing?
JavaScript Code
'use strict';
function canUse(feature = null, type = 'member', attribute = '', value = '') {
switch (type) {
case 'member':
return Boolean(feature);
case 'callable':
return typeof feature === 'function';
case 'eval':
return (() => {
try {
eval(feature);
return true;
} catch (error) {
return false;
}
})();
}
const isElement = () => document.createElement(feature).constructor.name !== 'HTMLUnknownElement';
const isAttribute = () => isElement() && attribute in document.createElement(feature);
switch (type) {
case 'element':
return isElement();
case 'attribute':
return isAttribute();
case 'value':
return (() => {
if (!isAttribute()) return false;
const element = document.createElement(feature);
element.setAttribute(attribute, value);
if (element[attribute] !== value) return false;
return true;
})();
default:
return null;
}
}
console.log(' Eval: ' + canUse('(new (class { #private = 0; getPrivate() { return this.#private; } })).getPrivate();', 'eval'));
console.log(' Member: ' + canUse(window.document, 'member'));
console.log(' Callable: ' + canUse(document.createElement, 'callable'));
console.log(' Element: ' + canUse('canvas', 'element'));
console.log('Attribute: ' + canUse('input', 'attribute', 'placeholder'));
console.log(' Value: ' + canUse('input', 'value', 'type', 'file'));
Console Output
