我从一个隐藏的全局变量中获得了一个值,而我认为它应该以未定义作为响应.

我重写和压缩了原始代码,因为我不敢相信它应该可以工作,但它仍然可以工作.输入的id为"Num1".JS写错了,要求输入id为"数字1".当代码加载时,Num1为空,但show函数中的Num1从输入元素获取值,并将其显示在带有输出id的标签中.这怎么可能呢?我试过 chromium 合金和EDGE,结果一样.

"use strict";
const num1 = document.getElementById("number1");
const outp = document.getElementById("output");

function show() {
  const num1 = parseFloat(globalThis.num1.value);
  outp.innerHTML = num1;
}
<div>
  <label for="num1">Number 1</label>
  <input type="number" id="num1">
</div>
<button type="button" onclick="show()">Show</button>
<div>Output <label id="output"></label></div>

推荐答案

这之所以有效,是因为您的HTML代码中设置了id属性的元素会自动创建为全局window对象的属性(在本例中为globalThis).此行为有时称为"命名元素":

"use strict";
console.log(window.test); // `test` is a named element
console.log(test); // ends up accessing window.test
console.log(globalThis.test); // also same as accessing window.test
<input type="text" id="test" />

上面,仅仅因为我们为文本输入设置了id/"test",它现在就在window上创建了一个名为test的全局属性,我们可以访问该属性.虽然这是可行的,但避免以这种方式访问元素,而使用.querySelector().getElementById()等方法则是considered best practice

在本例中,您使用const来声明num1变量,这样num1变量就不会像省略const或使用var那样成为window(globalThis)对象上的属性.因此,window对象上自动添加的num1属性保持不变,不会被您的变量声明覆盖.这意味着在执行globalThis.num1操作时,您不是在访问在周围作用域中声明的变量,而是在访问自动添加的窗口属性,该属性是在为元素赋予id时自然获得的(如上面的代码片断所示).这就是为什么您的代码即使在没有const num1声明的情况下也可以工作:

"use strict";
// const num1 = document.getElementById("number1");
const outp = document.getElementById("output");

function show() {
  const num1 = parseFloat(globalThis.num1.value);
  outp.innerHTML = num1;
}
<div>
  <label for="num1">Number 1</label>
  <input type="number" id="num1">
</div>
<button type="button" onclick="show()">Show</button>
<div>Output <label id="output"></label></div>


我的建议是,如果需要在函数中访问外部全局变量,则停止跟踪外部全局变量,以避免所有这些问题.要做到这一点,只需在函数中调用非num1的变量即可:

"use strict";
const num1 = document.getElementById("num1"); // update to the correct value
const outp = document.getElementById("output");

function show() {
  const num1Float = parseFloat(num1.value);
  outp.innerText = num1Float; // use innerText or textContnt if the content you're setting is just text, not HTML
}
<div>
  <label for="num1">Number 1</label>
  <input type="number" id="num1">
</div>
<button type="button" onclick="show()">Show</button>
<div>Output <label id="output"></label></div>

Javascript相关问答推荐

如果使用React Select ,如何将CSS类添加到元素中?

验证嵌套 colored颜色 代码的结果

将未等待的未处理的错误promise 转变为警告@ changeTicksAndRejections(由当时的抛出错误创建)

为什么子组件没有在reaction中渲染?

Fastify错误:CORS策略已阻止从起源api-dev.example.com上的MLhttp请求

如何在JavaScript中通过一次单击即可举办多个活动

禁用从vue.js 2中的循环创建的表的最后td的按钮

在分区内迭代分区

使用JavaScript在ionic Web应用程序中更新.pane和.view的背景 colored颜色

vscode扩展-webView Panel按钮不起任何作用

在Angular中将样式应用于innerHTML

colored颜色 检测JS,平均图像 colored颜色 检测JS

在带有背景图像和圆形的div中添加长方体阴影时的重影线

当id匹配时对属性值求和并使用JavaScript返回结果

如何将未排序的元素追加到数组的末尾?

传递方法VS泛型对象VS事件特定对象

打字脚本中方括号符号属性访问和拾取实用程序的区别

在Java脚本中录制视频后看不到曲目

构建器模式与参数对象输入

JavaScript&;Reaction-如何避免在不使用字典/对象的情况下出现地狱?