试图在一些js代码中找出'this'

时间:2013-07-04 03:04:55

标签: javascript

<input type="button" value="Button 1" id="btn1"  />
<input type="button" value="Button 2" id="btn2"  />
<input type="button" value="Button 3" id="btn3"  onclick="buttonClicked();"/>


<script type="text/javascript">  

  function buttonClicked(){        
    var text = (this === window) ? 'window' : this.id;    
    console.log( text);        
  }

  var button1 = document.getElementById('btn1');  
  var button2 = document.getElementById('btn2');


  button1.onclick = buttonClicked;

  button2.onclick = function(){
    buttonClicked();
  };

</script>

问题:

点击按钮1,显示:btn1,点击按钮2和按钮3,显示:window,为什么不btn2btn3

2 个答案:

答案 0 :(得分:4)

button1.onclick = buttonClicked;

它会显示btn1,因为onclick(button1的属性)现在指向buttonClicked,因此此调用的上下文为button1

button2.onclick = function(){
    buttonClicked();
  };

它显示window因为onclick(button2的属性)现在指向一个匿名函数,并且在该函数内部调用buttonClicked();(类似于window.buttonClicked();),这个的上下文来电是window

你的情况用button3:

<input type="button" value="Button 3" id="btn3"  onclick="buttonClicked();"/>

相当于:

btn3.onclick = function(){
    buttonClicked();
}

因为当你内联声明你的事件处理程序时,浏览器会自动将你的代码包装在一个匿名函数中。

答案 1 :(得分:1)

<强>基本

当点击处理程序定义如下:

button.onclick = some_function;

单击按钮时,JavaScript实际上会运行此命令:

some_function.call(button, ...);

换句话说,对按钮元素的引用在处理程序中绑定为this

匿名函数

让我们看一下button2的点击处理程序的定义:

button2.onclick = function() {
    buttonClicked();
}

匿名函数绑定到按钮,但是对buttonClicked()的调用根本没有绑定(所以它隐含地绑定到window的范围)。要达到预期的效果,您需要这样做:

button2.onclick = function() {
    buttonClicked.apply(this, arguments);
}

<强>内联

无论你在onclick属性中写什么,都会被用作点击处理程序的正文。所以你的代码:

<input ... onclick="some_function();" />

相当于:

button3.onclick = function() {
    some_function();
};

如您所见,它的行为与button2相同。

<强>加成

为了它的乐趣,你可以编写你的内联点击处理程序:

<input ... onclick="buttonClicked.call(this);" />

Results

顺便说一句,编写事件处理程序内联不是一个很好的做法,你应该看看使用addEventListener()attachEvent()(IE)注册它们,但请注意它们的行为不同。