The snippet below spits out an error that CustomElementParent
is not defined when I try to extend from it in CustomElementChild
.
When I remove the ! customElements.get('custom-element-parent')
check, it works.
In my case, CustomElementParent
is in a third party script, so I can’t actually remove the if statement.
I guess this is a problem of conditionally defining a class. Is there any way to extend this class if it is conditionally defined?
<script>
if (! customElements.get('custom-element-parent')) {
class CustomElementParent extends HTMLElement {
constructor() {
super();
}
}
customElements.define('custom-element-parent', CustomElementParent);
}
if (! customElements.get('custom-element-child')) {
class CustomElementChild extends CustomElementParent {
constructor() {
super();
alert('test');
}
}
customElements.define('custom-element-child', CustomElementChild);
}
</script>
<custom-element-child></custom-element-child>
2
Answers
Scope. Classes have scope, same as variables.
(We don’t talk about
var
. Point is,class
works likelet
/const
/function declarations in strict mode.)If you can’t change how
CustomElementParent
is scoped and you can’t put your code in its scope, you can’t access it that way. You can look it up in the custom element registry instead:Full example:
Like
let
andconst
,class
declarations are block-scoped. So the scope of theCustomElementParent
declaration is theif
block, and it’s not accessible when you get to the secondif
block.You can solve this by declaring the names outside the scope, then assigning them with class expressions.