今天在用原生js写demo的时候发现一个有意思的小现象,那就是可以直接根据元素的id去获取对应的元素。
起先是我定义了四个btn,每个btn都是根据getElementById
来获取元素,然后给元素绑定事件,在调试的时候都挺好,到了后面我打算优化流程去掉一个btn的时候我才发现第四个btn一直没有定义
<div>
<button id="btn1">test1</button>
<button id="btn2">test2</button>
<button id="btn3">test3</button>
<button id="btn4">test4</button>
</div>
<script>
const btn1 = document.getElementById('btn1');
const btn2 = document.getElementById('btn2');
const btn3 = document.getElementById('btn3');
// 绑定事件
const bindEvent = () => {
console.log(btn5);
btn1.addEventListener('click', a, false);
btn2.addEventListener('click', b, false);
btn3.addEventListener('click', c, false);
btn4.addEventListener('click', d, false);
};
(() => {
bindEvent();
})();
</script>
简化的代码如上所示,起先我以为是代码又缓存,因为我用了express,但是我重启清除缓存以后,btn4依然可以使用,于是我就写了个简单的demo,不用express访问来测试一下。
此时我猜测可能是浏览器的优化,因为id是唯一的,所以可能浏览器读取到这个id元素的时候就自动定义了一个id同名变量。所以我猜测类名应该是不可以的,而如果在js中定义了同名的变量或常量,之前浏览器默认定义的id同名变量则会被覆盖。
<body>
<div id="app"></div>
<div id="test"></div>
<div class="aaa"></div>
</body>
<script>
const test = 123;
console.log(app); // <div id="app"></div>
console.log(test); // 123
console.log(aaa); // Uncaught ReferenceError: aaa is not defined
</script>
验证的结果和我的猜想一样。我倒是觉得思路挺不错的,根据浏览器读取html的顺序可以保证js的优先级一定是高于这个默认值的,所以也不会影响代码逻辑,但是如果不清楚的话确实会让人有点摸不着头脑。
🚩查了一下后发现这个特性是很早就有的特性了,大概七八年前就有人发现这个问题了,算是一个历史遗留的特性。不过这种方式也是非标准的所以大家还是尽量别用吧。