如何使用这个关键字?

时间:2018-01-22 05:12:54

标签: javascript

嗨,我正在制作一个番茄钟。我希望在用户按下按钮时允许计时器每100毫秒增加或减少一次。 mousedown和clickUpdate的运行条件非常相似。

clickUpdate的整个代码依赖于使用此关键字来实现该目标。但是,如何让setInterval继承或有权访问此关键字?这指的是mousedown的按钮对象是一种方法。

https://codepen.io/jenlky/pen/ypQjPa?editors=0010

var timer;
const session = document.getElementById("session");
const breaktime = document.getElementById("break");
const mins = document.getElementById("mins");
const secs = document.getElementById("secs");

function clickUpdate () {
    // if data-action = increase and its under session-input, increase session.value else increase breaktime.value
    if (this.dataset.action === "increase") {
        if (this.parentElement.className === "session-input") {
            // if session.value is 60 mins, this increase click changes it to 1 min
            if (session.value === "60") {
                session.value = 1;
            } else {
                session.value = Number(session.value) + 1;
            }
            mins.innerText = session.value;
            // if breaktime.value is 60 mins, this increase click changes it to 1 min
        } else {
            if (breaktime.value === "60") {
                breaktime.value = 1;
            } else {
                breaktime.value = Number(breaktime.value) + 1;
            }
        }
    }

    // if data-action = decrease and its under session-input, decrease session.value else decrease breaktime.value
    if (this.dataset.action === "decrease") {
        if (this.parentElement.className === "session-input") {
            // if session.value is 1 min, this decrease click changes it to 60 mins
            if (session.value === "1") {
                session.value = 60;
            } else {
                session.value = Number(session.value) - 1;
            }
            mins.innerText = session.value;
            // if breaktime.value is 1 min, this decrease click changes it to 60 mins
        } else {
            if (breaktime.value === "1") {
                breaktime.value = 60;
            } else {
                breaktime.value = Number(breaktime.value) - 1;
            }
        }
    }
    console.log(this);
}

// Problem is how can I let clickUpdate or setInterval(function(){},100) inherit this
// setInterval's function doesn't seem to inherit or have any parameters
// I'm not sure how forEach thisArg parameter works, or how to use bind, or how to use addEventListener last parameter
function mousedown() {
    var obj = this;
    timer = setInterval(clickUpdate, 100);
}

function mouseup() {
    if (timer) {
        clearInterval(timer);
    }
}

const buttons = Array.from(document.getElementsByClassName("symbol"));
mins.innerText = session.value;
//buttons.forEach(button => button.addEventListener("click", clickUpdate));
buttons.forEach(button => button.addEventListener("mousedown", mousedown));
buttons.forEach(button => button.addEventListener("mouseup", mouseup));
console.log(session);

2 个答案:

答案 0 :(得分:2)

使用this定义的函数中的function () ...值通常取决于函数的调用方式。如果您致电a.myFunction(),则该功能中的this将引用a。如果您致电myFunction(),则this将为undefined或全局对象,具体取决于您使用的是严格模式还是草率模式。

通常,让回调函数使用特定this值的最简单方法是使用.bind(n)。这基本上创建了原始函数的包装版本,this值被锁定为n

setInterval(clickUpdate.bind(this), 100);

然后,我的偏好是根本不使用this。它令人困惑并且有古怪的行为,往往需要各种人为的解决方法(正如您所经历的那样)。你可以像在这里一样轻松地传递值:

function mousedown(e) {
    timer = setInterval(clickUpdate, 100, e.target);
}

答案 1 :(得分:0)

一个技巧是创建一个单独的引用(全局或至少在共同的祖先范围内),从所需的级别保存对“this”引用的引用。

执行此操作后,您可以在setInterval函数中引用它。

示例:

var scope = this;
this.name = 'test';
setInterval(function() {
    console.log(scope.name); // should print 'test' every 1 second
},1000);