题目:
尝试实现注释部分的Javascript代码,可在其他任何地方添加更多代码(如不能实现,说明一下不能实现的原因):
var Obj = function(msg){
this.msg= msg;
this.shout= function(){
alert(this.msg);
}
this.waitAndShout= function(){
//隔五秒钟后执行上面的shout方法
}
}
本题考察内容是来自Javascript权威指南第171页函数调用。
原话:关键字this没有作用域的限制,嵌套的函数不会从调用它的函数中继承this。另外,this是一个关键字,不是变量,也不是属性名。Javascript不允许给this赋值。如果嵌套函数作为方法调用,其this的值指向调用他的对象。如果嵌套函数作为函数调用,其this不是全局对象(非严格模式下)就是undefined(严格模式下)。很多人误以为调用嵌套函数时,this会指向调用外层函数的上下文。如果你想访问这个外部函数的this值,需要将this保存在一个变量里,这个变量和内部函数都在同一个作用域里。通常使用变量self保存this。
答案:
var Obj = function(msg){ //Obj()作为函数调用,他的this对象可以指代全局对象window
this.msg = msg;
this.shout=function(){ //this.shout属于嵌套函数作为方法调用。所以如果要调用他的话, 应该写成this.shout() 如果this是对象ob,则调用他方式为ob.shout()
alert(this.msg);
}
this.waitAndShout=function(){ <span style="font-family: Arial, Helvetica, sans-serif;">//this.waitAndShout属于嵌套函数作为方法调用</span>
var self=this; //因为下面的setInterval是作为函数调用的,所以需要用self保存这个this指代的<strong><span style="color:#cc0000;">当前</span></strong>对象
setInterval(function(){self.shout()},5000); //setInterval("self.shout()",5000);这个也可以 但是 setInterval(self.shout(),5000);这个出错
}
}
注意!!! 上面的函数只是定义,还没有执行。如果需要执行,可以用以下两种方式执行。
方法一:
var Obj = function(msg){
this.msg = msg;
this.shout=function(){
alert(this.msg);
}
this.waitAndShout=function(){
var self=this;
setInterval("self.shout()",5000);
};
<strong><span style="color:#cc0000;">this.waitAndShout();</span></strong>
}
Obj("hello world");
方法二:
var Obj = function(msg){
this.msg = msg;
this.shout=function(){
alert(this.msg);
}
<strong><span style="color:#cc0000;">this.waitAndShout=(function(){
var self=this;
setInterval("self.shout()",5000);
}());</span></strong>
this.waitAndShout();
}
其中
<strong><span style="color:#cc0000;">this.waitAndShout=(function(){
var self=this;
setInterval("self.shout()",5000);
}());</span></strong>
这一部分表示函数表达式在定义后立即执行。
Javascript权威指南第167页第二行就是例子。