博客
关于我
表单中的一些隐晦的bug
阅读量:467 次
发布时间:2019-03-06

本文共 1208 字,大约阅读时间需要 4 分钟。

当我们尝试调用 form.submit() 时,实际上是访问了 form 对象的 submit 属性,而不是 HTMLFormElement 原型链中的 submit 方法。这是因为 JavaScript 在查找属性时,优先检查对象本身的属性,然后才是原型链中的方法。

要解决这个问题,我们需要明确区分调用对象本身的属性和原型链的方法。以下是详细的分析过程:

分析过程

  • 获取 form 对象:代码中使用 document.getElementById('form') 获取了一个具有 id="form" 的表单对象。这一步没有问题。

  • 调用 submit 方法:在调用 form.submit() 时,JavaScript 首先检查 form 对象本身是否有名为 submit 的属性。

  • 检查 form 对象的属性:由于 form 对象有一个名为 submit 的 input 元素,form.submit 返回的是该 input 节点,而不是原型链中的方法。

  • 类型错误发生:因此,form.submit 的类型是 HTMLElement(即 input 元素),而不是函数,因此调用 form.submit() 导致错误。

  • 原因

    JavaScript 的属性访问机制是按顺序查找的。首先,检查对象本身的属性。如果找到,返回该属性的值;如果没有找到,继续检查原型链中的方法。因此,当 form 对象上存在与 submit 函数名称相同的属性时,会导致混淆。

    特别是,当 form 对象有一个 submit 属性(如 input 元素),它会遮盖原型链中的 submit 方法。因此,在调用 form.submit 时,会优先返回这个属性,而不是方法。

    解决方法

    要避免这种问题,可以采取以下措施:

  • 避免在对象本身存储与原型链中方法名称相同的属性。使用不同的属性名。

  • 明确区分调用原型链方法

    • 使用 HTMLFormElement.prototype.submit.call(form)
    • 或者,使用 form[HTMLFormElement.prototype.submit].call(form),这在 older JavaScript 引擎中可能更有用。
  • 显式地使用原型链方法,如 form.submit() 只有在没有重叠属性名的情况下才有效。

  • 优化后的代码

        Form Submit 错误分析    

    结论

    调用 form.submit() 会错误地返回输入字段的值,而不是原型链中的 submit 方法。要解决这个问题,确保调用原型链中的方法,避免对象本身的属性与原型链方法名称冲突。使用明确的方法调用,比如 HTMLFormElement.prototype.submit.call(form), 可以正确引发表单提交行为。

    转载地址:http://mhcdz.baihongyu.com/

    你可能感兴趣的文章
    wxWidgets源码分析(4) - 消息处理过程
    查看>>
    wxWidgets源码分析(5) - 窗口管理
    查看>>
    wxWidgets源码分析(6) - 窗口关闭过程
    查看>>
    wxWidgets源码分析(7) - 窗口尺寸
    查看>>
    wxWidgets源码分析(8) - MVC架构
    查看>>
    wxWidgets源码分析(9) - wxString
    查看>>
    Mybatis Generator最完整配置详解
    查看>>
    Elasticsearch集群升级指引
    查看>>
    webpack打包less与sass
    查看>>
    [白话解析] 深入浅出熵的概念 & 决策树之ID3算法
    查看>>
    [梁山好汉说IT] 梁山好汉和抢劫银行
    查看>>
    [记录点滴] OpenResty中Redis操作总结
    查看>>
    [源码解析] 消息队列 Kombu 之 基本架构
    查看>>
    [源码分析] 消息队列 Kombu 之 启动过程
    查看>>
    [源码分析] 消息队列 Kombu 之 Consumer
    查看>>
    [源码分析] 消息队列 Kombu 之 mailbox
    查看>>
    抉择之苦
    查看>>
    wx.NET CLI wrapper for wxWidgets
    查看>>
    Silverlight for linux 和 DLR(Dynamic Language Runtime)
    查看>>
    微软网络数据包分析工具 Microsoft Network Monitor 3.2
    查看>>