JavaScript 中的“onclick”和“this”

2024-04-28

我很困惑:

  • 为什么内联onclick我们要写onclick="hello()",而在JS中我们应该写btn.onclick=hello或者btn.addEventListener('click',hello);

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

  • 我不明白最后两个按钮

根据w3school,在函数中,this 指的是全局对象。https://www.w3schools.com/js/js_this.asp https://www.w3schools.com/js/js_this.asp

在常规函数中,this 关键字表示调用该函数的对象,可以是窗口、文档、按钮或其他任何东西。https://www.w3schools.com/js/js_arrow_function.asp https://www.w3schools.com/js/js_arrow_function.asp

const 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>

about this values.

  1. 箭头函数捕获和always使用他们的词汇this值,意味着当他们的箭头函数表达式 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions被评价。求值通常发生在执行赋值操作或计算参数列表中包含箭头函数的函数调用的参数值时。

    • 箭头函数不能用作构造函数。
  2. 使用非箭头函数作为构造函数调用new https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new (or super https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/super当扩展一个类时)将正在构造的对象视为它们的this value.

  3. 绑定函数保存并使用this value作为第一个参数提供给bind method https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind的另一个函数。

    • 绑定函数忽略它们保存的this如果作为构造函数调用,则值 - 但这很少见,可以被视为边缘情况,并且是一般不推荐 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind#Bound_functions_used_as_constructors.

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

  4. 使用它们调用的函数call https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call or apply https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply对象方法采用它们的this来自(第一个)的值thisValue提供给的参数call or apply,受 JavaScript 模式影响:

    • 严格模式下null or undefined提供的值thisValue被用作函数的this价值。在草率模式 https://developer.mozilla.org/en-US/docs/Glossary/Sloppy_mode然而,null or undefined被替换为window在拨打电话之前。

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

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

    例如。形式上的召唤

    someObject.methodName( optionalArgumentList)
    

    this in methodName指的是someObject如果该方法是常规函数。

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

function a () {
    "use strict";
    console.log("in strict mode functions the default this is ", this);
};
let b = function() {
    console.log("but in non strict mode,  the default this is ",
        this === window ? "window" : this
    );
}

a(); // undefined
b(); // window
  1. 在对全局的调用中以文本字符串形式提供的代码函数构造函数 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function, SetTimeout https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout、相关的计时器调用和 HTML 源中的事件属性,本身被视为“脚本”并创建 一个函数

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

    • 在严格模式下运行如果严格模式is在源码中调用。

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

  2. The this评估代码时的值eval https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval超出了这个问题的范围,但为了完整性:

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

    • 间接调用eval use window(即全局对象)为this 即使他们调用严格模式 (Ref https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval#Descriptionhttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval#Description.)

    这也是一种边缘情况,因为它存在危险,eval should 永远不要被使用,因为你可以 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval#Do_not_ever_use_eval!.


HTML 中的内联事件处理程序

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

    onEventName="text"

被转换为事件处理函数HTML解析器使用相当于的步骤

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

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

    function( event) {
          // include attribute text here as body code
    }
    
  3. 将函数保存为元素的属性,名称与属性相同。例如。此时一个元素带有onclicktext 属性还将有一个onclick属性是一个函数。

  4. 将函数添加到元素的内部事件处理程序映射。 https://html.spec.whatwg.org/multipage/webappapis.html#activate-an-event-handler实际上,这意味着实际的事件处理使用侦听器映射,而不是在元素上查找处理程序函数。

Warning

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

    HTML 解析器创建的处理程序有一个遗留的作用域链,它最少地搜索事件属性所属的元素,周围的元素form元素(如果有),以及document查找名称时到达全局对象之前的对象 - 这可能会导致隐蔽的错误 https://stackoverflow.com/q/52599614/5217142.


question 1

为什么内联onclick我们要写onclick="hello()",而在JS中我们应该写btn.onclick=hello或者btn.addEventListener('click',hello);

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

在 JS 中,设置onclick到一个函数对象,或者调用addEventListener使用函数作为第二个参数,将函数添加到与元素关联的处理程序映射中。如果函数名后面有括号,则使用onclick举个例子:

  onclick = myFunction();

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


question 2

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

在从内联 onclick 属性创建的事件处理函数内,this does请参阅按钮。如果您使用如下代码调用另一个函数hello(),您正在对它进行不合格的调用,因此被调用的函数使用其默认值this值 - 即window如果被调用的函数在草率模式下运行。

继“HTML 中的内联事件处理程序”之后,您could传递this(指的是按钮)和event对象作为参数值,如果您想要:

onclick="hello(this, event)"

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


question 3

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

创建事件处理函数

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

按钮标签的事件属性文本中未调用严格模式,因此两者onclick and tes处于草率模式。tes被无条件调用,因此它使用并记录其默认值this值为window.

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


question 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>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JavaScript 中的“onclick”和“this” 的相关文章

随机推荐