Javascript setTimeout内部的变量表示它未定义,但外部的变量表示它已定义
我有课。我需要在超时时间内完成一些http工作。我面临的问题是超时内的http变量一直说它未定义Javascript setTimeout内部的变量表示它未定义,但外部的变量表示它已定义,javascript,angular,Javascript,Angular,我有课。我需要在超时时间内完成一些http工作。我面临的问题是超时内的http变量一直说它未定义 export class MyClass { http:Http: constructor(private http:Http) { this.http = http; } sendFriendRequest(){ this.http.post( ...//http variable is defined here
export class MyClass {
http:Http:
constructor(private http:Http) {
this.http = http;
}
sendFriendRequest(){
this.http.post( ...//http variable is defined here
setTimeout(function(){
this.http.post(... //http is not defined here
}
}
}
您应该在这里使用箭头函数,以保留此函数的存在
setTimeout(()=>{
this.http.post(... //http is not defined here
})
这样做时,函数内部的这个
被绑定到外部上下文。这与:
setTimeout(function(){
this.http.post();
}.bind(this));
使用
function(){…
解决此问题最常用的两种方法:
1) 使用额外变量存储在“this”之外
2) 使用箭头函数
this.http.post( ...//http variable is defined here
setTimeout(() => {
that.http.post(... //http is not defined here
}
}
第一种方法是旧的ES5,您不需要任何编译器,对于ES6版本(#2),您需要使用类似babel的东西
有关arrow函数和babel的更多信息,请参见此处:原因是setTimeout中的回调函数位于不同的词法环境中。这就是为什么在ES6+中可以使用
=>
定义函数。这样,函数中的代码与函数共享相同的范围
要解决这个问题,您可以使用ES6+语法,其中使用(a,b,args){…}
而不是(a,b,args)=>{…}
:
setTimeout(() => {
this.http.post(...);
});
或使用ES5语法:
var root = this;
setTimeout(function(){
root.http.post(...);
});
希望这能有所帮助!在JavaScript中,
这个
关键字用于访问调用函数的上下文。JavaScript中的函数总是使用上下文调用,无论您使用.methodName()调用它们
语法或不带语法,除非在当前作用域中设置了'use strict'
标志
setTimeout(() => {
// Hey I can access 'this' in here!
}, 1000);
在没有如下上下文的情况下调用函数时:
myFunction()
运行时假定上下文是全局窗口对象(除非设置了'use strict'
标志,在这种情况下,上下文将是未定义的。)
注意:当ES6与Babel这样的transpiler一起使用时,默认情况下在输出中设置严格模式
在对象上保存对函数的引用时,可以使用点语法将对象作为“this”的上下文调用该函数
var myObj = {
myFunc: function(){}
};
// myFunc invoked like this, the value of 'this' inside myFunc will be myObj.
myObj.myFunc();
操纵“这个”:
调用并应用
您始终可以通过使用.call或.apply方法调用函数来更改其上下文。在这种情况下,您有一个匿名函数,它不是由您调用的,而是由setTimeout函数调用的。因此,您将无法利用.call或.apply
绑定
相反,您可以使用.bind方法创建具有自定义上下文的新函数。通过对匿名函数调用.bind(),将返回一个新函数,该函数将自定义上下文绑定到“this”。这样,您可以将自定义绑定函数作为数据传递给setTimeout
setTimeout(function(){
// your code.
}.bind(this), 1000);
现在,在匿名函数中,“this”关键字将绑定到正确的值
词汇“this”:
但是,在ES6中,当使用箭头函数时,有关“this”的规则会更改。如果使用此语法,您将看到“this”的上下文将与当前范围中的任何内容保持不变
setTimeout(() => {
// Hey I can access 'this' in here!
}, 1000);
保存引用:
如果您查看Babel的编译输出,您将看到Babel通过使用_this1、_this2等保存对“this”的引用来跟踪上下文
要自己使用此方法,只需声明一个新变量(通常使用'that'或'self'),并在匿名函数中使用它访问值,如下所示:
var self = this;
setTimeout(function(){
self.http.post...
});
希望这有帮助
为了获得更多解释,developer.mozilla.org有一个。这是因为这个
上下文:我们真的需要4个答案来回答这个问题吗?这些答案本质上都是说“使用箭头函数来获得适当的这个
上下文”?@MarkRajcok是的,只有3个答案是不够的!谢谢你的回答!完美的答案加上解释+1:)谢谢你的信息!如果在第二个示例中我们用箭头函数替换函数()
,它会起作用吗?如果不会,为什么?