我试图在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? 我确信我对这一点有些困惑,所以提前感谢任何解释:)
答案 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)
};
bind(this)
,此处未指向myObj
对象。这指向全球对象。为什么?因为代码运行的上下文是全局上下文(任何函数之外的代码)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)