为了账号安全,请及时绑定邮箱和手机立即绑定

javascript中的“onclick”和“this”

javascript中的“onclick”和“this”

慕的地10843 2021-10-14 17:08:53
我很迷惑:为什么inline onlick,我们必须写onclick="hello()",但是在JS中,我们应该写btn.onclick=hello or btn.addEventListener('click',hello);对于常规函数,为什么使用 inline onlick,“this”指的是窗口,而对于 js 调用,“this”指的是按钮。我不明白最后两个按钮根据w3school,在一个函数中,this指的是全局对象。 https://www.w3schools.com/js/js_this.asp在常规函数中,this 关键字表示调用该函数的对象,可以是窗口、文档、按钮或其他任何东西。 https://www.w3schools.com/js/js_arrow_function.aspconst arrayBtn = document.querySelector(".arrowFunc");const regBtn = document.querySelector(".regFunc");hello = () => console.log("i am arrow function" + this);function hiii(){  console.log("i am regular function" + this);}arrayBtn.addEventListener("click", hello);regBtn.addEventListener("click", hiii);<button onclick="hello()">This calls an arrow function with an inline onclick</button><button class="arrowFunc">This calls an arrow function with event listener</button><button onclick="hiii()">This calls an regular function with an inline onclick</button><button class="regFunc">This calls an regular function with event listener</button><button onclick="function tes(){console.log(this)}tes()">button</button><button onclick="console.log(this)">button</button>[Log] i am arrow function[object Window] <br>[Log] i am arrow function[object Window] <br>[Log] i am regular function[object Window] <br>[Log] i am regular function[object HTMLButtonElement] <br>[Log] Window {document: #document, window: Window, NaN: NaN, nalert: function, obj: {name: "my_obj"}, …} <br>[Log] <button onclick="console.log(this)">button</button>
查看完整描述

2 回答

?
至尊宝的传说

TA贡献1789条经验 获得超10个赞

关于this价值观。

  1. 箭头函数捕获并始终使用它们的词法 this值,这意味着在评估它们的箭头函数表达式时有效的那个值。求值通常发生在执行赋值操作或为参数列表中有箭头函数的函数调用计算参数值时。

    • 箭头函数不能用作构造函数。

  2. 作为构造函数调用的非箭头函数new(或super在扩展类时)将正在构造的对象视为它们的this值。

  3. 绑定函数保存并使用this value提供的作为另一个函数bind方法的第一个参数。

    • this如果作为构造函数调用,绑定函数会忽略它们保存的值 - 但这种情况很少被视为边缘情况,通常 不推荐使用

    • 绑定箭头函数对其this值没有影响,但可用于预定义一组参数值。

  4. 使用它们的callapply对象方法调用的this函数从thisValue提供给callor的(第一个)参数中获取它们的值apply,受 JavaScript 模式约束:

    • 在严格模式nullundefined提供thisValuethis值用作函数的值。然而在草率模式下,null或在拨打电话之前undefined被替换window

    • 可以使用这些方法(例如提供参数)调用箭头和绑定函数,但使用它们自己的记录this值。

  5. 如果上述规则均不适用,则作为对象方法显式调用的函数将使用该对象作为其this值。

    EG 形式调用

    someObject.methodName( optionalArgumentList)

    thisinmethodName是指someObject该方法是否为常规函数。

  6. 在严格模式下,this非限定函数调用中的默认值为undefined。在草率模式下(从首次引入 JavaScript 开始)thiswindow. 演示:


显示代码片段


  1. 代码中调用全球提供的文本字符串函数的构造, SetTimeout,相关的计时器调用,并在HTML源事件的属性,被视为自己的权利“脚本”,并创建了一个功能



    虽然这会改变函数的默认 this值,但这也是一种边缘情况,因为在编写可维护的代码时,不推荐使用这些创建函数的方法。

    • 如果提供的源代码调用严格模式,则以草率模式运行,

    • 如果在源中调用严格模式则以严格模式运行。

  2. this评估代码时的值eval超出了这个问题的范围,但为了完整性:


    这也是一个边缘情况,因为它的危险性,eval不应该被使用,因为你可以

    • 直接调用从调用上下文eval继承this,除非评估的代码调用严格模式 - 在这种情况下thisundefined在代码评估期间。

    • 间接调用eval使用window(即全局对象),this 即使它们调用严格模式Ref。)


HTML 中的内联事件处理程序

表单的 HTML 标记中的事件处理程序内容属性

    onEventName="text"

HTML 解析器使用等效于的步骤转换为事件处理函数

  1. 将文本保存为属性的字符串值。

  2. 使用 JavaScript 解析器/编译器通过将文本包含在表单模板中来从文本创建事件处理程序函数

    function( event) {       // include attribute text here as body code }
  3. 将函数另存为与属性同名的元素的属性。EG 在这一点上,具有onclick文本属性的元素也将具有作为onclick函数的属性。

  4. 将该函数添加到元素的内部事件处理程序映射。 实际上,这意味着实际的事件处理使用侦听器映射,而不是在元素上查找处理函数。

警告

  • HTML onEventName 属性早于 DOM 的标准化和引入addEventListener

    HTML 解析器创建的处理程序有一个遗留范围链,它最低限度地搜索事件属性所属的元素、周围form元素(如果有的话)以及document在查找名称时到达全局对象之前的对象 - 这可能会导致模糊的错误



问题 1


为什么inline onlick,我们必须写onclick="hello()",但是在JS中,我们应该写btn.onclick=hello or btn.addEventListener('click',hello);

HTML 事件处理程序属性用作由 HTML 解析器创建的事件处理程序函数的主体代码。要调用hello,属性文本必须提供进行调用的源代码,例如hello()

在 JS 中,将 an 设置onclick为函数对象,或addEventListener将函数作为第二个参数调用,会将函数添加到与元素关联的处理程序映射中。如果括号放在函数名之后,onclick例如:

  onclick = myFunction();

调用该函数并尝试将其返回值用作处理函数 - 如果返回值不是函数,则很少发生。大多数情况下,这是一个错误,而不是预期的结果。


问题2


对于常规函数,为什么内联onclick中,“this”指的是窗口,而js调用时,“this”指的是按钮。

在从内联 onclick 属性创建的事件处理函数内部,this 确实引用了按钮。如果你用类似的代码调用另一个函数hello(),你就是在对它进行不合格的调用,所以被调用的函数使用它的默认this值——即,window如果被调用的函数在草率模式下运行。

从“在HTML内嵌事件处理程序”下面,你可以通过对this(指按钮)和event对象,如果你想一个参数值:

onclick="hello(this, event)"

JavaScript 中提供的处理程序函数直接进入元素的事件处理程序映射,并由事件系统以按钮作为其this值调用(可能使用callapply,因为添加的处理程序addEventListener不作为元素属性值维护)。



问题 3


<button onclick="function tes(){console.log(this)}tes()">button>/button>

创建事件处理函数

function onclick(event) {     function tes(){         console.log(this)     }     tes() }

在按钮标记的事件属性文本中未调用严格模式,因此onclick和 tes都处于草率模式。tes被无条件调用,因此它使用并记录其默认thiswindow.

关于“关于这个值”,规则 1-5 均不适用,因此规则 6 生效。



问题 4


<button onclick="console.log(this)">button</button>

创建处理函数

function onclick(event) {     console.log(this) }

this事件系统将按钮元素作为其值调用它,就像它对任何其他处理程序一样。console.log正在显示日志中按钮的外部 HTML。如果您更改this为字符串,日志将告诉您它是一个 HTMLButtonElement 元素:

<button onclick="console.log(this.toString())">button</button>


查看完整回答
反对 回复 2021-10-14
  • 2 回答
  • 0 关注
  • 308 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信