在javascript

时间:2016-05-05 15:53:43

标签: javascript this bind

我试图在javascript中理解这个关键字,我已经阅读了各种文章,但似乎我仍然有些困惑。

例如,让我们考虑以下代码:

/*
 * script.js
 */

var data = 'global data';

var myObj = {

  data: 'object data',

  scope: function() {
      console.log(this.data);
  }

};


myObj.scope();    // print "object data"

因此在这种情况下,scope()函数的调用上下文是对象,而 this 绑定到对象本身。

现在让我们添加一些HTML ..

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title></title>
</head>
<body>

<input type="button" value="clickme" id="button">

<script src="script.js"></script>

</body>
</html>

..并在按钮上单击事件侦听器以触发scope()函数

document.getElementById("button").addEventListener('click', myObj.scope, false);

// click on the button => print "undefined"

在单击事件上,此指的是没有数据属性的按钮对象,因此它正确打印undefined。 现在我想使用bind方法(而不是call或apply)在声明时解决这个问题。因此我写道:

/*
 * script.js
 */

var data = 'global data';

var myObj = {

  data: 'object data',

  scope: function() {
      console.log(this.data);
  }.bind(this)

};

document.getElementById("button").addEventListener('click', myObj.scope, false);


myObj.scope();    // print "global data"

// click on the button => print "global data"

似乎我绑定了全局对象(窗口)而不是myObj。为什么?第一个示例中 console.log(this.data)行中使用的 this 关键字与 bind行中使用的 关键字之间的区别是什么?这个)在最后一个例子中?两者都不应该引用myObj? 我确信我对这一点有些困惑,所以提前感谢任何解释:)

3 个答案:

答案 0 :(得分:0)

这是解决方案,您需要将eventHandler绑定到您想要的上下文。请看下面的例子:

var data = 'global data';

var myObj = {
  data: 'object data',
  scope: function() {
      console.log(this.data);
  }
};

document.getElementById("button").addEventListener('click', myObj.scope.bind(myObj), false);

如果您不想打扰bind,请参阅ES6上使用Fat箭头的示例(您今天可以使用它,只需阅读有关Babeljs的内容)。参见示例:

var data = 'global data';

var myObj = {
  data: 'object data',
  scope: function() {
      console.log(this.data);
  }
};

document.getElementById("button").addEventListener('click', () => myObj.scope(), false);

要了解详情,请阅读文章(https://john-dugan.com/this-in-javascript/),该文章通过4个简单步骤解释了这一点

答案 1 :(得分:0)

似乎不可能直接在对象内部将函数绑定到对象本身,但是在对象声明之外扩充对象似乎也有效,并且您不必担心每次绑定上下文想要调用函数:

var myObj = {
  data: 'object data',
};

myObj.scope = function() {
  console.log(this.data);
}.bind(myObj);

您怎么看?

答案 2 :(得分:0)

  

为什么呢?这行中使用的this关键字有什么区别   第一个例子中的console.log(this.data)和中使用的一个   line bind(this)在最后一个例子中?不应该两者都提到   MyObj中?我确信我对这一点感到困惑,所以谢谢   提前解释:)

在上一段代码中:

var myObj = {

  data: 'object data',

  scope: function() {
      console.log(this.data);
  }bind(this)

};
  1. 首先,你在绑定之前错过了一个点,但我认为这只是错字
  2. bind(this),此处未指向myObj对象。这指向全球对象。为什么?因为代码运行的上下文是全局上下文(任何函数之外的代码)
  3. 如果您确实要将myObj.scope的上下文绑定到myObj,您仍然无法在下面执行此操作,在运行时,您将遇到can't read property of undefined错误:
  4. -

    var myObj = {
    
      data: 'object data',
    
      scope: function() {
          console.log(this.data);
      }.bind(myObj)
    
    };
    

    为什么呢?因为上面的代码片段是一个javascript语句,当javascript引擎试图解释该语句时,myObj尚未初始化。它是在初始化期间,因此当函数bind(myObj)时,myObj未定义。你需要用2个语句来做:

    var myObj = {
    
      data: 'object data',
    
      scope: function() {
          console.log(this.data);
      }
    };
    myObj.scope = myObj.scope.bind(myObj)