为什么 JavaScript 控制台打印不一致的值?

Why JavaScript console prints inconsistent value?

<body>
    <div id="wrap">
        <input type="button" id="btn" onclick="alpha"  value="ccc">
    </div>
    
    <script>
        
        console.log(btn.attributes.getNamedItem("onclick")) ;
        console.log(btn.attributes.getNamedItem("onclick").value) ;

        btn.attributes.getNamedItem("onclick").value = "beta()";
        function beta(){
            alert(`alpha changed to beta`);
        }

    </script>
</body>

关于

console.log(btn.attributes.getNamedItem("onclick"));

这一行打印 onclick="beta()",

console.log(btn.attributes.getNamedItem("onclick").value);
此行打印 alpha

以上两行在覆盖行之前写的完全相同
btn.attributes.getNamedItem("onclick").value = "beta()";

我认为这两个 console.log() 行应该以相同的方式运行

        console.log(btn.attributes.getNamedItem("onclick")) ;
        console.log(btn.attributes.getNamedItem("onclick").value) ;

唯一的区别是第二个打印第一个的 .value
但是这些不同的结果从何而来呢?

简短的回答是,通过记录 onclick,您正在记录 事件对象 ,而使用 onclick.value,您正在记录 事件处理回调参考 (alpha).

现在,您可以直接通过其 id 属性访问 JavaScript 中的元素,而不是使用 DOM 查询技术。当你给一个元素一个 id 时,它变成了 window 对象的全局 属性,如果你只通过 id 访问它,你正在访问一个 [=15] =] 属性,其中包含对对象的引用。 window 不是 DOM 的一部分,因此不是标准的。

但是,如果您通过 document.querySelector() 访问元素,这是一种 DOM 查询方法,您会得到一个 DOM 对象,并且会看到标准的 DOM 属性.

不需要使用getNamedItem()setAttribute()getAttribute()。只需直接访问 属性 即可访问该数据(即 btn.onclick = foo())。

此外,不鼓励使用事件属性(如 onclick)。这是一种设置事件的较旧方法,但不如 .addEventListener() 的现代标准强大,而后者正是您应该使用的方法。

这是与 DOM 元素交互的 standards-based 方式的示例。以下是 standards-based 代码,将在所有现代客户端中产生一致的结果。

<body>
    <div id="wrap">
        <!-- Notice that the id and onclick attributes have been removed. -->
        <input type="button" value="ccc">
    </div>
    
    <script>
        // Instead of direct referencing elements via their id attribute,
        // use a standard DOM querying method to get a DOM element reference
        const btn = document.querySelector("input[type='button']");
        
        // Instead of wiring up elements to events in HTML with event attributes,
        // use the modern standard of .addEventListener() which allows for
        // multiple event handlers for any given event.
        btn.addEventListener("click", alpha);
        btn.addEventListener("click", beta);
        
        function alpha(event){
            // To access details about a DOM element, just access the 
            // property directly. In this event callback function, the 
            // object that fired the event can be referenced via its DOM
            // reference (btn), the event target (event.target), or the object
            // that caused the event callback to be called (this).
            console.log("Hello from alpha");
            console.log("You clicked: ", event.target);
            console.log("The element is a: ", this.nodeName);
            console.log("...with a type of: ", btn.type);
            console.log("...with a value of: " + event.target.value);
            console.log("The event being handled is: ", event.type);
            console.log("And the event object itself is: ", event);
        }
        function beta(){
            console.log("Hello from beta");
        }

    </script>
</body>