绑定到 javascript 中的这个关键字

bind to this keyword in javascript

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

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

/*
 * 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"

在单击事件中 this 引用没有数据 属性 的按钮对象,因此它正确打印未定义。 现在我想在声明时使用绑定方法(而不是调用或应用)来解决这个问题。因此我写:

/*
 * 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"

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

这里是解决方案,您需要将事件处理程序绑定到您想要的上下文。看下面的例子就清楚了:

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 arrows 的示例(你今天可以使用它,只需阅读有关 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 个简单的步骤对此进行了解释

似乎无法直接在对象内部将函数绑定到对象本身,但在对象声明之外扩充对象似乎也可行,而且您不必担心每次都绑定上下文您要调用函数的时间:

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

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

你怎么看?

Why? Which is the difference between the this keyword used in the line console.log(this.data) in the first example and the one used in the line bind(this) in the last example? Should not both refer to the myObj? I am sure I have some confusion about this point, so thanks in advance for any explanation :)

在您的最后一个代码片段中:

var myObj = {

  data: 'object data',

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

};
  1. 首先,你在绑定之前少了一个点,但我认为这只是错字
  2. bind(this),这里this并不指向myObj对象。 this 指向全局对象。为什么?因为代码所在的上下文 运行 是全局上下文(任何函数之外的代码)
  3. 如果你真的想将myObj.scope的上下文绑定到myObj,你仍然不能像下面那样做,在运行时,你会遇到can't read property of undefined错误:

-

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)