从同一对象的不同实例中触发另一个实例的函数
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从同一对象的不同实例中触发另一个实例的函数相关的知识,希望对你有一定的参考价值。
我是javascript的初学者,我正在努力弄清楚如何使用一个实例的函数来触发另一个实例中的函数,反之亦然,这两个版本都是同一个类。让我解释一下我的意思。
我的项目是用Javascript构建一个番茄钟。番茄钟是一个你在指定时间内工作的过程(例如25分钟),然后短暂休息(5分钟),然后重复。时钟应该无限期地或者在用户停止之前一直向后运行。
我需要完成一个时钟来触发另一个时钟的开始,反之亦然。
我为每个计时器使用完全独立的,略有不同的功能构建了一个工作程序(冗余很多)。我试图通过创建一类Timers并从中构建每一个来简化我的代码。那就是我被困住的地方。
我的Timer类中有一个函数,当计时器到达零时,需要调用另一个计时器的倒计时开始(Codepen上的第126行)。我怎样才能做到这一点?
感谢您提供的任何帮助。
这是我在Codepen上的项目:https://codepen.io/lieberscott/pen/baRpgx?editors=1010
我的Javascript代码如下:
let session; // session Timer object instance
let btimer; // break Timer object instance
let s_off; // boolean for whether session timer is off or on
let s_timer; // reference to session timer html element
let s_stop; // reference to session stop HTML button
let s_increase; // reference to session increase HTML button
let s_decrease; // reference to session decrease HTML button
// same variables as above for break timer
let b_off;
let b_timer;
let b_stop;
let b_increase;
let b_decrease;
$(document).ready(function() {
s_off = true;
s_timer = $("#timer");
s_stop = $("#stop");
s_increase = $("#increase");
s_decrease = $("#decrease");
b_off = true;
b_timer = $("#breaktimer");
b_stop = $("#breakstop");
b_increase = $("#breakincrease");
b_decrease = $("#breakdecrease");
session = new Timer(1, 60, s_off, s_timer, s_stop, s_increase, s_decrease);
btimer = new Timer(5, 60, b_off, b_timer, b_stop, b_increase, b_decrease);
// increase session minutes
$(s_increase).on("click", function() {
if (session.off) {
session.min++;
session.sec = 00;
s_timer.html(session.min + ":" + session.sec);
}
});
// decrease session minutes
$(s_decrease).on("click", function() {
if (session.off) {
if (session.min > 1) {
session.min--;
}
session.sec = 00;
s_timer.html(session.min + ":" + session.sec);
}
});
// increase break minutes
$(b_increase).on("click", function() {
if (btimer.off) {
btimer.min++;
btimer.sec = 00;
b_timer.html(btimer.min + ":" + btimer.sec);
}
});
// decrease break minutes
$(b_decrease).on("click", function() {
if (btimer.off) {
if (btimer.min > 1) {
btimer.min--;
}
btimer.sec = 00;
b_timer.html(btimer.min + ":" + btimer.sec);
}
});
// begin session timer by clicking on the timer itself
$(s_timer).on("click", function() {
session.time();
});
// stop session timer
$(s_stop).on("click", function() {
session.off = true;
session.stopClock(session.intervalFunction);
});
// stop break timer
$(b_stop).on("click", function() {
btimer.off = true;
btimer.stopClock(btimer.intervalFunction);
});
});
class Timer {
constructor(min, sec, off, disp, stopButton, increaseButton, decreaseButton) {
this.min = min; // minutes
this.minsSet = min; // minutes again, this will be used to reset the timer
this.sec = sec;
this.off = off; // boolean saying whether timer is off or not
this.disp = disp; // HTML display
this.stopButton = stopButton;
this.increaseButton = increaseButton;
this.decreaseButton = decreaseButton;
this.func;
}
time() { // function fired when the timer is clicked
if (this.off) {
this.off = false;
this.func = this.intervalFunc();
}
}
intervalFunc() { // set the interval of the timer
setInterval(function() {this.countdown();}, 1000); // ERROR HERE
}
countdown() { // interval to complete for duration of timer
// check if clock reaches zero
if (this.sec == 0) {
this.min--;
this.sec = 60;
if (this.min < 0) {
this.min = this.minsSet;
this.sec = 0;
this.off = true;
this.time(); // this needs to trigger, not this.time(), but the OTHER object's time() function
this.stopClock(this.func); // clearInterval() function below
}
}
// if clock is not at 0:00, display new time
this.sec--;
let m = this.min.toString();
let s;
if (this.sec < 10) {
s = "0" + this.sec.toString()
}
else {
s = this.sec.toString();
}
this.disp.html(m + ":" + s);
}
stopClock() {
clearInterval(this.func);
}
}
1)我尝试了你的代码并修复了一些bug,你的setInterval问题是因为“this”指向那里的window对象。
2)为了调用另一个对象time()方法,首先你需要知道你正在使用哪个对象,所以我在类中添加了一个类型变量,然后在倒计时函数中添加了一个检查。这笔中有变化:
https://codepen.io/yaduvanshi/pen/dJRdeR?editors=0010
intervalFunc() { // set the interval of the timer
var that =this;
setInterval(function() {that.countdown();}, 1000); // ERROR HERE
}
我认为您正在寻找的解决方案是Javascript为您提供的.bind()或.call()(Function.prototype.bind())。例如,.bind()函数将特定对象实例作为参数。你可以在这里阅读https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Function/bind
以上是关于从同一对象的不同实例中触发另一个实例的函数的主要内容,如果未能解决你的问题,请参考以下文章
为啥我能够从在同一对象的另一个实例上调用的方法访问一个实例的私有实例变量? [复制]
将类对象实例作为参数从 main() 传递给另一个类对象实例