function Aaa(){
this.a = 12;
setInterval(this.show,1000);
}
Aaa.prototype.show = function(){
console.log(this.a);
}
var a = new Aaa();
按照理解window里没有show的方法,结果打印出来的是a对象,理解不了,求大神指点

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
setInterval里面的this指向的是window对象。
准确说应该是setInterval第一个回调函数运行时,内部上下文this, 而不是传参时那个this。
更正一下其中的错误,
回答这个问题,只用个二三句话是很难回答得清楚,要用旁敲侧击的讲法,说实在都有点对又不太对。
我猜想你应该是想要打印12的结果,而不是现在的
Aaa {a:12}这个结果。问题在于setInterval你猜对了。最大的问题来源是,JS是个脚本语言,定义是定义,执行是执行,对于函数更是如此,你作了函数的定义或当值来传递,并不代表它一定在执行时不会因此改变,
this值就是有可能改变结果的变因。这段代码会怎么执行?顺序又是什么,大致上模拟一下:
呃,上面看完了。那如何让
setInterval(this.show,1000);在执行时能打印出this.a的值,说起来简单,改成像下面这样就行了,但为何能这样作,说起来也是满大一串的:下面题外话,只是撰写调试的小建议供参考。
第1是为什么要用同样的变量名称?这例子里出现了二个a变量,一个在函数里,一个在外面(全局),英文字元有26个,再加上可以大小写与各种长短不一的组合,一定要用同样的变量名称,是要考验自己还是考验来看代码的人?在show函数中到底是想要输出函数中的a,还是外面的对象a?
第二是为什么在调试时要用
setInterval而不用setTimeout,这两个不是类似的功用,差异是setTimeout只执行一次而已。问我说这么讲究作什么?问题是setInterval是一直执行下去,同样的代码你执行一次看到结果不对,难道第二次有可能变正确?而且这在调试时非常不便,我如果把代码贴到主控台测,它一直执行不停,不就又要想办法先关掉它再作第二次修正再执行。我都要先改写过代码如下才能调试:
补充说明
setInterval的第一个传入值,要是个回调函数,等到时间到要移回主执行线中执行的。回调函数,预设呼叫它的必是window物件,也就是函数区块中的this预设是window。看到很多回答的人也误解了,顺便谈一下,下面这两个例子有何不同?
第1例在执行到这行时,实际会转变为下面这样,这才算函数:
在本题目中,最后的第1例与第2例的
this值都是window对象,所以分别要执行的是下面这两个,结果写后面注解:真正要解让
setInterval能够是输出a对象中的a属性,只有一种途径,让传入的这个回调函数的this值钉住,让它必定指到执行当下的对象,所谓的钉住主要是要取得在执行的那一时刻的this值,你可以记住它或直接把原来的输出语句改写。目前我知道有三种解决的方案,以下列出来:
1. 用
bind方法。这是个函数中自带的方法,可以用个物件来"绑定"某个函数后,回传一个新已绑定的函数。一般用这个方案,不过要习惯一下。2. 用
setInterval的第三个传入参数值,把this传入作为that用,执行的是that.show。注意这方式在IE9之前的浏览器版本不相容。3. IIFE解法,也是要传入
this到IIFE中,与上面概念类似。IIFE一执行时就会固定住that,这里是执行that.show(),而不是有可能会变的this.show():以上,算补充内容,有兴趣可以套用试试。
当执行到
new Aaa()时,function Aaa中的this就已经绑定成新创建的object了。可以绑定 this
this指的是,调用函数的那个对象
Javascript的this用法
setInterval里的函数this指向window,没错,这也正是打印a对象的原因;调用了
a对象(其实是原型)的show方法,这也没错,因为在Aaa里你给setInterval传的this就是a对象;function Aaa(){
}
Aaa.prototype.show = function(){
}
var a = new Aaa();//这里a引用了新对象Aaa
执行new Aaa()后,构造函数以及原型上的this将指向a,
setInterval(this.show,1000)等同于setInterval(a.show,1000)
这个打印的就是window.a