【发布时间】:2016-05-05 15:53:43
【问题描述】:
我正在尝试理解 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 指的是没有 data 属性的按钮对象,所以它正确地打印 undefined。 现在我想在声明时使用绑定方法(而不是调用或应用)来解决这个问题。所以我写:
/*
* 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吗? 我确信我对这一点有些困惑,所以提前感谢您的任何解释:)
【问题讨论】:
-
您需要将
myObj.scope.bind(myObj)传递给addEventListener。您不能在对象字面量内绑定函数。 -
这是因为你传入 just 函数
myObj.scope本身 - 想想如果你将它从myObj中取出并粘贴为一个函数本身;它如何知道您尝试访问的范围?您的数据是否需要以这种方式构建?相反,您应该有一个函数,该函数接受要引用的范围的参数 -
我知道我可以使用这样的调用(或应用)来解决问题: document.getElementById("button").addEventListener('click', function() {myObj.scope.call(myObj )}, 错误的);只是想知道我是否可以在声明时(使用绑定)而不是在调用时修复它
标签: javascript this bind