JavaScript中的“ onclick”和“ this”

时间:2019-09-13 02:31:42

标签: javascript html onclick this onclicklistener

我很困惑:

  • 为什么要使用内联onlick,我们必须编写onclick =“ hello()”,但是在JS中,我们应该编写btn.onclick = hello或btn.addEventListener('click',hello);

  • 对于常规函数,为什么使用内联onlick,“ this”是指窗口,但是对于js调用,“ this”是指button。

  • 我不明白最后两个按钮

根据w3school,在函数中,它是指全局对象。 https://www.w3schools.com/js/js_this.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>

2 个答案:

答案 0 :(得分:1)

内联hello()中的文本<button onclick="hello()">实际上是一个小型javascript程序,您永远都不要使用它,它是使任何事情正常工作的过时老式方法,应该被忘记

相反,javascript中的正确方法如下:

function hello() {}
button.onclick = hello

其中hello是函数(不是javascript程序)的名称

为什么this是当前按钮?可以使用不同的this

调用所有函数

如果需要,您可以使用其他hello调用this函数

hello.call({turkey: true})

这就是调用hello并提供{turkey: true}作为this对象的方式

这是html元素调用事件处理程序的标准,该事件处理程序的元素为this对象

欢呼?追逐

答案 1 :(得分:0)

关于this值。

  1. 箭头函数捕获并始终使用其词法this值,这意味着在评估其arrow function expression时生效的值。通常在执行赋值操作或为参数列表中具有箭头功能的函数调用计算参数值时进行评估。

    • 箭头函数不能用作构造函数。
  2. 使用new(或扩展类时为super)称为构造函数的非箭头函数将正在构造的对象视为其this的值。

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

    • 如果作为构造函数调用,绑定函数将忽略其保存的this值-但这很少见,可以认为是边缘情况,not generally recommended

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

  4. 使用其callapply对象方法调用的函数从提供给this的(第一个)thisValue参数中获取其call值或apply,具体取决于JavaScript模式:

    • 在严格模式下,为null提供的undefinedthisValue值用作函数的this值。但是,在sloppy mode中,在进行呼叫之前,nullundefinedwindow替换。

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

  5. 未提供上述任何规则 ,显式调用为对象方法的函数将对象用作其this值。< / p>

    E.G。以表格的形式

    someObject.methodName( optionalArgumentList)
    
    如果方法是常规函数,则this中的

    methodName引用someObject

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

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. 在对全局Function constructorSetTimeout的调用,相关计时器调用以及HTML源代码中的事件属性中,以文本字符串形式提供的代码本身被视为“脚本”正确并创造 一个功能

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

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

    虽然这会更改函数的 default this值,但这也是一种极端情况,因为在编写可维护的代码时,不建议使用所有创建函数的方法。

  2. 使用eval评估代码时的this值不在此问题的范围内,但出于完整性考虑:

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

    • eval的间接调用将window(即全局对象)用作this ,即使它们调用严格模式({{3} }。)

    这也是一个极端情况,因为eval应该Ref存在危险。


HTML中的内联事件处理程序

HTML格式的事件处理程序内容属性

    onEventName="text"

HTML解析器使用等效于

的步骤将其转换为事件处理函数。
  1. 将文本保存为属性的字符串值。

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

    function( event) {
          // include attribute text here as body code
    }
    
  3. 将函数另存为元素的属性,并与属性具有相同的名称。例如。此时,具有onclick文本属性的元素也将具有onclick属性,它是一个函数。

  4. 将函数添加到元素的内部never be used because you can中,实际上这意味着实际的事件处理使用侦听器映射,而不是在元素上查找处理函数。

警告

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

    由HTML解析器创建的处理程序具有一个旧的作用域链,该链最小限度地搜索事件属性所属的元素,周围的form元素(如果有)以及document对象,然后到达全局对象查找姓名-可能导致event handler map.


问题1

  

为什么要使用内联onlick,我们必须编写onclick =“ hello()”,但是在JS中,我们应该编写btn.onclick = hello或btn.addEventListener('click',hello);

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

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

  onclick = myFunction();

该函数被调用,并尝试将其返回值用作处理程序函数-如果返回值不是函数,则几乎不会发生。通常,这是一个错误,而不是预期的结果。


问题2

  

对于常规功能,为什么在嵌入式onclick中,“ this”是指窗口,而在js调用中,“ this”是指button。

在由嵌入式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()
}

按钮标记的事件属性文本中未调用严格模式,因此onclicktes均处于草率模式。 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>