在javascript中绑定到此关键字

bind to this keyword in javascript

本文关键字:关键字 绑定 javascript      更新时间:2023-09-26

我正在努力理解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"

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

/*
 * 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(this)行使用的关键字有什么区别?不应该两者都引用myObj吗?我确信我对这一点有一些困惑,所以提前感谢您的解释:)

为什么?行中使用的this关键字之间的区别是什么第一个示例中的console.log(this.data)和最后一个例子中的换行符?不应同时引用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错误:

-

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

为什么?因为上面的代码片段是一条javascript语句,所以当javascript引擎试图解释该语句时,myObj还没有初始化。它是在初始化过程中,所以当函数bind(myObj)时,myObj是未定义的。你需要用两个语句来完成:

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

似乎不可能将函数直接绑定到对象内部的对象本身,但在对象声明之外增强对象似乎也能起作用,而且每次调用函数时都不必担心绑定上下文:

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

你觉得怎么样?

以下是解决方案,您需要将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个简单的步骤解释了这一点