理解为什么我不能在 Javascript "Class" 中引用 this.property
Understanding why I cannot reference this.property in Javascript "Class"
我有以下交互式视频播放器的原型 class...
// default constructor
function BrightPlayer() { };
// prototypes for basic properties
BrightPlayer.prototype.CurrentCourse = null;
BrightPlayer.prototype.CurrentTopic = null;
BrightPlayer.prototype.CurrentSubTopic = null;
BrightPlayer.prototype.CurrentTimestamp = null;
BrightPlayer.prototype.VideoSelector = null;
BrightPlayer.prototype.VideoObject = null;
BrightPlayer.prototype.Heartbeat = function () {
setInterval(this.ApplicationPulse, 1000);
};
BrightPlayer.prototype.ApplicationPulse = function () {
// javascript errors occurs on the next line.
// VideoObject is undefined.
this.CurrentTimestamp = this.VideoObject.currentTime;
console.log('pulse....');
};
BrightPlayer.prototype.Init = function () {
// My thoughts were that the following line would initialize
// the VideoObject in this instance, and subsequent calls
// in the Application Pulse would have this reference, but it's not working
this.VideoObject = document.getElementById("brightplayer-video");
this.Heartbeat();
};
实例化 class 并从我的主 HTML 页面启动 Init。
<script>
var Aplayer = new BrightPlayer();
Aplayer.Init();
</script>
但是,如果我添加 this.VideoObject = document.getElementById("brightplayer-video");在 ApplicationPulse 函数内部,它有效。
即
BrightPlayer.prototype.ApplicationPulse = function () {
this.VideoObject = document.getElementById("brightplayer-video");
this.CurrentTimestamp = this.VideoObject.currentTime;
console.log('pulse....');
};
虽然这很草率,但我不想在每个脉冲上都进行元素查找。在尝试将 Javascript classes 与 C# classes 联系起来时,我一定是遗漏了什么。如果您能提供任何帮助,我们将不胜感激。
问题来了,因为使用了this
。
setInterval
被定义为浏览器 window
对象的函数。从 setInterval
调用时 this
的上下文不同,即 window
。所以一切都在 window
上分配。 属性 window.VideoObject
不存在,因此您的代码不起作用。
this
在 javascript 中的工作方式与在 C# 中不同。在 javascript 中,this
受 函数调用方式 的约束(忽略箭头函数)。因此,在您的情况下,该函数是从 window
对象调用的。
因此,要解决您的问题,您需要正确绑定 this
。有不同的方法。
- 在另一个变量中存储对此函数的引用
self = this;
- 使用
bind
功能。 setInterval(this.ApplicationPulse.bind(this), 1000))
BrightPlayer.prototype.Heartbeat = function () {
setInterval(this.ApplicationPulse, 1000);
};
当您将 this.ApplicationPulse
传递给 setInterval
时,它会在不同的上下文中调用。您希望通过将 ApplicationPulse
绑定到 this
:
来显式定义 ApplicationPulse
将 运行 的上下文
BrightPlayer.prototype.Heartbeat = function () {
setInterval(this.ApplicationPulse.bind(this), 1000);
};
我有以下交互式视频播放器的原型 class...
// default constructor
function BrightPlayer() { };
// prototypes for basic properties
BrightPlayer.prototype.CurrentCourse = null;
BrightPlayer.prototype.CurrentTopic = null;
BrightPlayer.prototype.CurrentSubTopic = null;
BrightPlayer.prototype.CurrentTimestamp = null;
BrightPlayer.prototype.VideoSelector = null;
BrightPlayer.prototype.VideoObject = null;
BrightPlayer.prototype.Heartbeat = function () {
setInterval(this.ApplicationPulse, 1000);
};
BrightPlayer.prototype.ApplicationPulse = function () {
// javascript errors occurs on the next line.
// VideoObject is undefined.
this.CurrentTimestamp = this.VideoObject.currentTime;
console.log('pulse....');
};
BrightPlayer.prototype.Init = function () {
// My thoughts were that the following line would initialize
// the VideoObject in this instance, and subsequent calls
// in the Application Pulse would have this reference, but it's not working
this.VideoObject = document.getElementById("brightplayer-video");
this.Heartbeat();
};
实例化 class 并从我的主 HTML 页面启动 Init。
<script>
var Aplayer = new BrightPlayer();
Aplayer.Init();
</script>
但是,如果我添加 this.VideoObject = document.getElementById("brightplayer-video");在 ApplicationPulse 函数内部,它有效。
即
BrightPlayer.prototype.ApplicationPulse = function () {
this.VideoObject = document.getElementById("brightplayer-video");
this.CurrentTimestamp = this.VideoObject.currentTime;
console.log('pulse....');
};
虽然这很草率,但我不想在每个脉冲上都进行元素查找。在尝试将 Javascript classes 与 C# classes 联系起来时,我一定是遗漏了什么。如果您能提供任何帮助,我们将不胜感激。
问题来了,因为使用了this
。
setInterval
被定义为浏览器 window
对象的函数。从 setInterval
调用时 this
的上下文不同,即 window
。所以一切都在 window
上分配。 属性 window.VideoObject
不存在,因此您的代码不起作用。
this
在 javascript 中的工作方式与在 C# 中不同。在 javascript 中,this
受 函数调用方式 的约束(忽略箭头函数)。因此,在您的情况下,该函数是从 window
对象调用的。
因此,要解决您的问题,您需要正确绑定 this
。有不同的方法。
- 在另一个变量中存储对此函数的引用
self = this;
- 使用
bind
功能。setInterval(this.ApplicationPulse.bind(this), 1000))
BrightPlayer.prototype.Heartbeat = function () {
setInterval(this.ApplicationPulse, 1000);
};
当您将 this.ApplicationPulse
传递给 setInterval
时,它会在不同的上下文中调用。您希望通过将 ApplicationPulse
绑定到 this
:
ApplicationPulse
将 运行 的上下文
BrightPlayer.prototype.Heartbeat = function () {
setInterval(this.ApplicationPulse.bind(this), 1000);
};