JavaScript-的所有者;这";

JavaScript-的所有者;这";,javascript,class,methods,this,console.log,Javascript,Class,Methods,This,Console.log,我遵循了创建JavaScript秒表的方法,并尝试将其扩展为使用多个秒表(类的多个实例)。我遇到的问题是,当我试图在时钟滴答作响的时候显示当前值时,我需要硬编码类实例,因为使用“this”不起作用(在我使用console.log的行上)。我已将代码缩减到最低限度,以尝试理解这一方面,并已将我的内容粘贴到下面: function Timer(){ var time1 = null; var time2 = null; var timeLoop = null; fu

我遵循了创建JavaScript秒表的方法,并尝试将其扩展为使用多个秒表(类的多个实例)。我遇到的问题是,当我试图在时钟滴答作响的时候显示当前值时,我需要硬编码类实例,因为使用“this”不起作用(在我使用console.log的行上)。我已将代码缩减到最低限度,以尝试理解这一方面,并已将我的内容粘贴到下面:

function Timer(){
    var time1 = null;
    var time2 = null;
    var timeLoop = null;

    function getTime(){
        var day = new Date();
        return day.getTime();
    }

    this.start = function(){
        time1 = getTime();

        timeLoop = setInterval(function(){
            time2 = getTime();
            console.log(_Timer.duration());
            //console.log(this.duration());
        },500);
    }

    this.duration = function(){
        return (time1 - time2) / 1000;
    }

}       
我想下面的链接描述了我的问题,但我不太理解,无法在这里应用它。这个问题是因为所有者是this.start而不是this,我如何编辑代码使其与任何计时器实例一起工作

我包括了硬编码的值行和不起作用的“this”行

谢谢


Geraint

每当您看到
函数时,您都可以假定
的值发生变化,因此在间隔
的回调函数中,此
实际上是
窗口,而不是对象

简单的解决方法是将
这个
存储在一个变量中

function Timer(){
    var time1 = null;
    var time2 = null;
    var timeLoop = null;

    function getTime(){
        var day = new Date();
        return day.getTime();
    }

    this.start = function(){

        var self = this;

        time1 = getTime();

        timeLoop = setInterval(function(){
            time2 = getTime();
            console.log(self.duration());
        },500);
    }

    this.duration = function(){
        return (time1 - time2) / 1000;
    }

}    

如果希望
this
属性保持一致,则应绑定正在调用的函数

比如说,

setInterval(function(){/*code here*/}.bind(this),500)


这样,内部函数的
this
将与外部函数相同。

this
不是局部变量,因此不会保存在闭包中。您需要分配一个局部变量:

this.start = function(){
    var self = this;
    time1 = getTime();

    timeLoop = setInterval(function(){
        time2 = getTime();
        console.log(self.duration());
    },500);
}
尝试:


第一件事。Javascript不支持基于类的OOP。它的OOP以及它的继承是原型

以下是如何使用计时器示例实现原型OOP功能的示例:

function Timer(){
  var time1 = null;
  var time2 = null;
  var timeLoop = null;
}

Timer.prototype.getTime = function(){
    var day = new Date();
    return day.getTime();
}

Timer.prototype.start = function(){
    time1 = this.getTime();
    timeLoop = this.setInterval(function(){
        time2 = this.getTime();
        console.log(this.duration());
    }.bind(this),500);
}

Timer.prototype.duration = function(){
    return (time1 - time2) / 1000;
}
查看的“自定义对象”部分

在教程中显示的方式没有问题。只是这是一种更干净的方法,
bind
调用仅用于
console.log
语句,否则它会将
this
关联为
窗口。如果你摆脱了它,你也可以摆脱绑定。

使用它非常有效

var定时器={
开始:函数(){
setInterval(function(){console.log(this.duration());}.bind(this),1000);
}
}
timer.start();
但如果您使用的是箭头功能,则可能不需要:

const计时器={
开始(){
setInterval(()=>{console.log(this.duration());},1000);
}
}
timer.start();

将“这个”复制到“那个”。不要使用“self”或其他使调试复杂化的预定义变量名称。@dandavis-是的,这就是为什么每个人都使用
self
、插件、jQuery,甚至谷歌,因为它不好。当在全局范围外使用时,它不会与window.self发生任何冲突,仅仅因为某些东西很普通并不意味着它不会更好。我一直看到大量糟糕的js,我不会称使用self为“糟糕”。在执行错误的情况下,ReferenceError通常比TypeError更容易找到,因为它在错误消息中包含缺少的变量的名称。为什么要给闭包一个看不见的失败路径呢?如果有类似的东西失败的声音更大,没有缺点的话?在node之前,我对webworkers很感兴趣,在node中,self就像一扇窗户,但“任何其他名字的玫瑰闻起来都一样香”。。。
function Timer(){
  var time1 = null;
  var time2 = null;
  var timeLoop = null;
}

Timer.prototype.getTime = function(){
    var day = new Date();
    return day.getTime();
}

Timer.prototype.start = function(){
    time1 = this.getTime();
    timeLoop = this.setInterval(function(){
        time2 = this.getTime();
        console.log(this.duration());
    }.bind(this),500);
}

Timer.prototype.duration = function(){
    return (time1 - time2) / 1000;
}