gpt4 book ai didi

javascript - JS 模块如何防止内部定义的自定义元素暴露其 API?

转载 作者:数据小太阳 更新时间:2023-10-29 04:45:03 31 4
gpt4 key购买 nike

这不起作用:

<!-- wtf.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<title></title>
<script type="module" src="./wtf.js"></script>
</head>
<body>
<script>
const myElement = document.createElement('my-element')
document.body.appendChild(myElement)
myElement.callMe()
</script>
</body>
</html>

// wtf.js
customElements.define('my-element', class extends HTMLElement {
constructor() {
super()
}

callMe() {
window.alert('I am called!')
}
})

Firefox 在 myElement.callMe() 行向我抛出一个讨厌的异常.显然,"myElement.callMe is not a function "

我很困惑为什么会这样?据我了解,只要我输入 const myElement = document.createElement('my-element') ,我收到一个类型不是通用类型的对象 HTMLElement但是我写的我类(class)的一个对象扩展了HTMLElement !这个类公开了callMe .

我已经确认我对模块的使用似乎是这里的罪魁祸首。此代码按预期工作:

<!-- wtf.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<title></title>
</head>
<body>
<script>
customElements.define('my-element', class extends HTMLElement {
constructor() {
super()
}

callMe() {
window.alert('I am called!')
}
})

const myElement = document.createElement('my-element')
document.body.appendChild(myElement)
myElement.callMe()
</script>
</body>
</html>

是的,我知道模块中定义的内容仅限于此模块。但在这里,它甚至(对我而言)似乎都不是一个范围界定问题。例如,如果我在模块内部做类似的事情:

function callMe() {/*blah blah */}

window.callMe = callMe

然后我就可以使用callMe 在模块之外 无论如何,因为模块通过 export 以外的其他方式公开了此功能(这次通过将其分配给全局 window 对象)。

据我了解,我的用例中也应该发生同样的情况。即使我定义了 callMe在模块范围内的类中,此类方法应该可以在模块外部访问,因为它是通过调用 document.createElement('my-element') 公开的此类对象的属性。 .然而显然,这并没有发生。

这对我来说真的很奇怪。看起来好像模块是通过与类型无关的函数 return 纠缠(!!) 来强制执行其作用域的 - 所以在这种情况下,它就像模块神奇地部队 document.createElement转换它在继承层次结构中向上返回的对象(到 HTMLElement )?!?!这让我大吃一惊。

有人可以解开我的困惑吗?

(如果我在一个模块中定义了一个自定义元素,我该如何在这个模块之外公开它的 API?)

最佳答案

问题是 <script type="module"> implicitly has a defer attribute ,所以它不会立即运行。

Even though I define callMe in a class scoped to the module, this class method should be accessible outside of the module

是的,是的。问题在于它是异步定义的 :-) 要使用模块中的内容,您应该明确 import该模块声明依赖关系,以确保以正确的顺序对其进行评估。如果您的全局脚本是 defer,它也可以工作不知何故是红色的。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<title></title>
<script type="module" src="./wtf.js"></script>
</head>
<body>
<script type="module">
import './wtf.js';
// ^^^^^^^^^^^^^^^^^^
const myElement = document.createElement('my-element')
document.body.appendChild(myElement)
myElement.callMe()
</script>
</body>
</html>

关于javascript - JS 模块如何防止内部定义的自定义元素暴露其 API?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56986980/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com