三大件一些让人迷惑的地方(会不断更新)

该文会不断更新

1. button和input的一些迷惑之处

让我们敲下面几行代码

<input type="button" value="点击" />
<input type="submit" value="点击" />
<button >点击</button>

有意思的是运行后,呈现的效果完全相同。

form提交应该使用input:submit还是button:submit? - 知乎 (zhihu.com)

  • <button> 元素是一个更灵活的按钮,可以自定义外观和样式(可以包含文本、图像或其他 HTML 元素),并且可以在点击时执行 JavaScript 操作。如果它位于表单中且没有指定 type 属性,则默认为 “submit” 类型,可以提交表单。
  • <input type="button"> 是一个用于执行 JavaScript 操作的按钮,不会自动提交包含它的表单。
  • <input type="submit"> 是一个用于提交表单的按钮,当用户点击它时,将触发表单的提交动作。
  • 旧版本的浏览器可能对 <button> 元素的行为和样式支持不一致。但<button> 元素通常被认为是更语义化的选择

2. 明明getElementsByClassNamequerySelectorAll可以实现一样的功能为什么要弄两个

getElementsByClassName 是一个原生的 DOM 方法,快一些,返回的是一个动态的 HTMLCollection 对象,该对象会随着 DOM 的变化而实时更新。。

querySelectorAll 是在 DOM API 中引入的新方法,返回的是一个静态的 NodeList 对象

  1. 使用 getElementsByClassName 的应用场景:
    • 动态更新的元素集合:如果需要选择的元素集合需要实时更新,例如在用户交互或事件处理程序中动态添加或删除元素时(比如写todolist
    • 仅按类名选择元素:如果您只需要按类名选择元素,并且不需要使用其他选择器(如标签名、ID、属性等),getElementsByClassName 是一个更简洁的选择。
  2. 使用 querySelectorAll 的应用场景:
    • 复杂的选择器需求:如果您需要使用更复杂的选择器,例如使用层级选择器、伪类选择器等来选择元素,querySelectorAll 提供了更灵活的选择器语法,使您能够使用更多种类的选择器。
    • 静态节点列表:如果您需要获取一个静态的节点列表,并且不需要实时更新,querySelectorAll 可以提供更适合的功能。
    • 使用其他选择器:如果您需要按照标签名、ID、属性等其他选择器选择元素,querySelectorAll 提供了更广泛的选择器选项。

3. 如何区分NodelistHtmlCollection

一个例子(可以直接复制后运行)

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <ul>
      <li class="example"></li>
      <li class="example"></li>
      <li class="example"></li>
    </ul>
  </body>
  <script>
    // 使用querySelectorAll获取NodeList和getElementsByClassName获取HTMLCollection
    const nodeList = document.querySelectorAll("li");
    const htmlCollection = document.getElementsByClassName("example");

    // 访问节点数量
    console.log("NodeList length:", nodeList);
    console.log("HTMLCollection length:", htmlCollection);
    // 动态添加元素
    const ul = document.querySelector("ul");
    const li = document.createElement("li");
    li.textContent = "New Element";
    li.className = "example";
    ul.appendChild(li);

    // 验证差异
    console.log("Updated NodeList length:", nodeList.length); // 不会更新,3相当于快照
    console.log("Updated HTMLCollection length:", htmlCollection.length); // 实时更新,4
  </script>
</html>

4. 函数为什么是把原型传给对象,而不是本身传给对象?或者问为什么老是遇见构造函数里有原型,而原型里面又有构造函数?(23/12/8更新)

演示案例

function Person(name, age) {
  this.name = name;
  this.age = age;
}
console.log(Person.prototype.constructor === Person); // true

答:函数本身就是一种数据类型,它有自己的任务。它来当构造函数相当于就是为了建立一个原型和对象的桥梁,相当于它生产了一个(不严谨),然后把这个交给了新的实例。这也就解释了为什么构造函数的原型里面还要加一个构造函数,因为这个构造函数是给新生成的对象用的。

5.setPrototypeOf 与 Object.create区别(23/12/8)

这里又涉及到了动静问题,如果你之前理解了它们之间的区别也会很好理解

功能不同:
setPrototypeOf 方法用于直接修改一个对象的原型。]
Object.create 方法用于创建一个新对象,该新对象的原型被设置为传入的参数。

兼容性差异:(感觉可以忽略)
setPrototypeOf 方法是在 ECMAScript 2015 (ES6) 中引入的,因此在一些较旧的浏览器或环境中可能不受支持。
Object.create 方法在较新的浏览器和环境中得到广泛支持,包括现代的主流浏览器和 Node.js。

使用方式不同:
setPrototypeOf 方法需要直接操作现有的对象,通过传递新的原型对象来修改对象的原型。例如:Object.setPrototypeOf(obj, newPrototype)。
Object.create 方法是一个静态方法,用于创建一个新对象并设置其原型。例如:Object.create(proto)。

性能方面:
直接操作对象会快一些。

  • 20
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值