javascript setInterval回调函一点疑惑
本人新手, 学习javascript
定时器的时候遇到了一点疑惑, 可能是个老生常谈的问题了, 但是还是想请教一下各位前辈, 问题与代码如下:
var Cat = function() {
var o = {
say: function() {
console.log('say something');
}
}
setInterval(function(){
o.say()
}, 1000)
return o
}
var cat = Cat()
cat.say = function() {
console.log('Hello');
}
问题描述:
我定义了一个Cat
类(用的工厂模式), 然后这个类里面有一个方法say()
, 同时还有一个setInterval
执行这个'方法', 然后实例化这个类, 重新声明一次say()
这个方法.
我的困惑:
在于, 输出是'Hello', 而不是我一开始定义的那个类里面的那个方法, 这个地方不是特别理解
个人理解:
由于setInterval
传进来的回到函数是一个方法, 实际上那个 o 指代的是实例化以后的那个实例对象, 而不是一开始的那个类?
但是感觉好像有点懂了, 但是又有点不懂, 或者其实根本不懂, 到底该如何正确清晰理解这段代码的运行过程, 希望各位前辈能有一个详细的解答, 多谢.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
o
本来就是实例化后的对象,你每执行一次Cat
,就会有一个新的o
生成。o
的实例化在执行完var o = ...
后就完成了。试运行以下代码:
这时输出就是
这个问题其实和
setInterval
无关,你提供的代码中的setInterval
的回调函数持有的是对o
这个实例的引用,而不是对o.say
的引用,因此一秒后这个回调执行的时候,就会先找到o
,然后再去找o.say
;而我提供的代码中的setInterval
的回调函数持有的是对o.say
这个函数的引用,并且是对旧的o.say
的引用,因此一秒后这个回调执行的时候,就会直接找到旧的o.say
。不知这样你是否清楚了。
先是执行
Cat()
这个函数,在对象中定义了say()
方法,接着遇到了setInterval
,这是个异步任务,所以加入到异步队列中。然后接着执行cat.say = function() {console.log('Hello'}
,这时,实例对象cat的的say方法已经被重写。接着,同步任务执行完了,执行之前加入异步队列中的回调函数,所以输出结果为Hello
.要输出'say something'关键要在定时器回调中运行Cat中o的确切引用,也可以这样:
代码简化一下就是
画个图:
虽然setInterval的代码写在前面,但因为前三步都是同步任务,所以会先执行。
可以搜索一下JS的事件循环,同步任务代码先执行,setInterval和setTimeout这种宏任务会放在异步队列中等待同步任务完成后再执行。