我试图在JavaScript中的类函数中使用setTimeout()
。 setTimeout()
应该在同一个类中触发另一个方法,因此我传递它的函数被写为window.setTimeout("this.anotherMethod", 4000)
。这带来了问题:this
引用了调用对象,在setTimeout()
的情况下它是window
。如何使用附件返回对类对象本身的引用?
myObject = function(){
this.move = function(){
alert(this + " is running");
}
this.turn = function(){
alert(this + " is turning");
}
this.wait = function(){
window.setTimeout("this.run" ,(1000 * randomNumber(1,5)));
}
this.run = function(){
switch(randomNumber(0,2)){
case 0:
this.move();
break;
case 1:
this.turn();
break;
case 2:
this.wait();
}
}
}
答案 0 :(得分:63)
你可以这样做:
var that = this;
setTimeout(function () {
that.doStuff();
}, 4000);
您还可以bind
获取更简洁的代码(正如@Raynos最初指出的那样):
setTimeout(this.doStuff.bind(this), 4000);
bind
是一个标准的库函数,用于完全符合这种编码模式(即从词法上捕获this
)。
答案 1 :(得分:7)
您还可以将函数绑定到范围。
setTimeout(this.run.bind(this) ,(1000 * randomNumber(1,5)));
警告Function.prototype.bind
是ES5
答案 2 :(得分:5)
this
在javascript中可能会出现问题。
我通常通过在对象中使用this
别名来解决这个问题,这样每当我需要一个引用回到包含对象时我就可以使用别名。
MyObject = function ()
{
var self = this;
// The rest of the code goes here
self.wait = function(){
window.setTimeout(self.run ,(1000 * randomNumber(1,5)));
}
}
答案 3 :(得分:3)
this.wait = function(){
var self = this;
window.setTimeout(function() { self.run() } ,(1000 * randomNumber(1,5)));
}
所以你将对你正在调用的对象的引用存储在局部变量('self')中。
答案 4 :(得分:2)
this
对调用它的上下文很敏感。当您将字符串传递给setTimeout
时,那就是eval
在完全不同的背景下。
您需要保留this
的当前值(通过将其复制到另一个变量)并维护范围(不使用(隐含)eval
)。
this.wait = function(){
var self = this;
setTimeout(function () { self.run() },
(1000 * randomNumber(1,5))
);
}
答案 5 :(得分:2)
在主myObject
的顶部,对this
的当前值进行新的引用:
var self = this;
然后为您的计时器回调创建一个闭包,该闭包使用该新引用而不是setTimeout
将用作回调中的默认上下文的全局对象:
setTimeout(function() {
self.run();
}, 4000);
答案 6 :(得分:2)
var timeoutID = window.setTimeout(func, delay, [param1, param2, ...]);
在func
内,this
始终引用全局对象。你可以将当前对象传入func,
var timeoutID = window.setTimeout(func, delay, this);
function func(that) {...}
不幸的是它在IE中不起作用
答案 7 :(得分:2)
class A{
setTimeout(()=>{
// here this != undefined because of arrow function
},500);
}
答案 8 :(得分:1)
你有没有尝试过;
window.setTimeout("myObject.run" ,(1000 * randomNumber(1,5)));
答案 9 :(得分:1)
您可以只使用箭头函数语法:
setTimeout(() => {
this.doStuff();
}, 4000);
答案 10 :(得分:0)
您可以使用此代码,该代码适用于所有现代浏览器 -
setTimeout(function(thisObj) {thisObj.run();},1000,this);
参考:http://klevo.sk/javascript/javascripts-settimeout-and-how-to-use-it-with-your-methods/
答案 11 :(得分:0)
缩短方式。没有匿名功能。
body
{
background-color: #aaaaaa;
margin: 0px;
}
#page
{
margin: auto;
width: 940px;
background-color: #95bfca;
background-image: linear-gradient(left top, rgb(208,226,231) 0%, rgb(0,102,128) 80%);
background-image: -o-linear-gradient(left top, rgb(208,226,231) 0%, rgb(0,102,128) 80%);
background-image: -moz-linear-gradient(left top, rgb(208,226,231) 0%, rgb(0,102,128) 80%);
background-image: -webkit-linear-gradient(left top, rgb(208,226,231) 0%, rgb(0,102,128) 80%);
background-image: -ms-linear-gradient(left top, rgb(208,226,231) 0%, rgb(0,102,128) 80%);
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#d0e2e7', endColorstr='#006680', GradientType=0 );
}
#banner
{
margin: auto;
width: 936px;
height: 122px;
background-image: url("banner.jpg");
}
#tagline
{
margin: 10px;
padding: 10px;
border: 2px solid #783201;
font: italic 22px calibri, sans-serif;
text-align: center;
background-color: #fff5db;
}
#main
{
padding: 20px 15px;
overflow: hidden;
position: relative;
}
.mainelement
{
background-color: #fff5db;
border: 2px solid #783201;
padding: 10px;
}
#main h1
{
margin: 20px 0px;
font-weight: bold;
font-style: italic;
font-family: calibri, sans-serif;
font-size: 15px;
}
#main div p, #main div li
{
font: 15px calibri, sans-serif;
}
#main a
{
font: 15px calibri, sans-serif;
color: #783201;
}
#main .expandable
{
text-align: center;
padding-left: 5px;
background-image: url("expand.png");
background-repeat: no-repeat;
background-position: left center;
}
.underline
{
text-decoration: underline;
}
.italic
{
font-style: italic;
}
.inlineh1
{
font: italic bold 15px calibri, sans-serif;
}
#languagebar
{
margin: 20px 15px;
width: 100px;
float: left;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
.flag
{
margin: 5px;
border: none;
}
#french
{
background-image: url("French.png");
float: left;
}
#english
{
background-image: url("English.png");
float: right;
}
#content
{
width: 700px;
float: right;
}
#footer
{
margin: auto;
font: 12px calibri, sans-serif;
color: #ffffff;
text-align: center;
}
#footer a
{
font: 12px calibri, sans-serif;
color: #ffffff;
}
/*** menu ***/
#menu
{
background-color: #783201;
border-top: 3px solid #783201;
border-bottom: 3px solid #783201;
}
#innermenu
{
border-top: 1px solid #ffffff;
border-bottom: 1px solid #ffffff;
overflow: hidden;
}
.menuitem
{
float: left;
margin: 5px 33px;
padding-bottom: 10px;
background-image: url("menutwiddle.png");
background-repeat: no-repeat;
background-position: center bottom;
}
.menuitem a
{
font: 18px calibri, sans-serif;
color: #ffffff;
text-decoration: none;
}
.activeitem
{
background: url('menu-line.png') repeat-x bottom left;
position: relative;
}
.activeitem:before
{
position: absolute;
top: 0;
left: -6px;
bottom: 0;
width: 6px;
content: ' ';
background: url('menu-ball.png') no-repeat bottom left;
}
.activeitem:after
{
position: absolute;
top: 0;
right: -6px;
bottom: 0;
width: 6px;
content: ' ';
background: url('menu-ball.png') no-repeat bottom left;
}
/*** form ***/
input[type=text], textarea
{
border: 1px solid #783201;
}
input[type=submit]
{
padding: 5px 15px;
background: #783201;
border-radius: 5px 5px;
color: #fff;
border: 0;
box-shadow: 1px 1px 2px #888;
}
input[type=submit]:active
{
box-shadow: 0 0 0 #fff;
}
答案 12 :(得分:0)
建议不要使用字符串
来使用setTimeout或setIntervalsetTimeout("myFunction()", 5000);
//this is the same as
setTimeout(function(){ eval("myFunction()"); }, 5000)); //<-- eval == BAD
答案 13 :(得分:0)
进入更复杂的情况......类A有一个类型B的成员和一个调用setTimeout的方法,该方法调用类B上的方法。解决方法如下:
class A {
constructor(b) {
this.b = b;
}
setTimer(interval) {
setTimeout(this.b.tick.bind(this.b), interval);
}
}
class B {
constructor(name){
this.name = name;
this.ele = window.document.getElementById('B');
}
tick() {
console.log(this);
this.ele.innerText += ' ' + this.name;
}
}
在B.tick中将A.b绑定到此并且工作。
这是bind
:https://jsfiddle.net/jrme9hyh/
没有bind
的人失败了:https://jsfiddle.net/2jde8tq3/