标签:
最近用setTimeout、setInterval,因为要传入的函数要用到this,所以深入了解了一番!
setTimeout和setInterval函数的第三个参数本来只是定义语言类型,后来在非IE浏览器下支持传递参数,并且在不同浏览器下支持的不同。
原来的setTimeout函数定义:
var timeoutID = window.setTimeout(func, delay[, lang]);
在Chrome和FF下定义被修改:
var timeoutID = window.setTimeout(func, delay, [param1, param2, ...]);
var timeoutID = window.setTimeout(code, delay);
IE:不支持第三个参数。
Chrome:接受的参数=传递的参数个数。
FF:接受的参数=传递的参数个数+1
具体可参看:https://developer.mozilla.org/zh-CN/docs/DOM/window.setTimeout
建议看了上址,再看本文,效果更好!
程序员是看Code的,贴上一段详细注释过的精巧代码:
(function (w) { //ie传入第三个参数 if (! + [1, ]) { //除IE外,!+[1,]都是返回false (function (overrideFn) { //overrideFn应改为wrapCall w.setTimeout = overrideFn(w.setTimeout); w.setInterval = overrideFn(w.setInterval); })(function (originalFn) {//包装函数,仅供上二行调用,只一个参数一个类setInterval返回函数 originalFn.isPolyfill = true;//fix ie9-- //注意return替换函数,而非调用返回值。返回真正要被替换的setTimeout,setInterval return function (code, delay) {//这才是真正的overrideFn var me = this,//fix: 激活code所在的this作用域 args = Array.prototype.slice.call(arguments, 2); return originalFn(function () {//这里才调用原API if (typeof code == 'string') { eval(code); } else { code.apply(me, args); } }, delay); } }) } })(window);
很简练,猫也是自MDN修改而来!我注释得很详细,只要理解了匿名函数的调用就通了
现在可以测试一下:
myArray = ["zero", "one", "two"]; myArray.myMethod = function (sProperty) { alert(arguments.length > 0 ? this[sProperty] : this); }; setTimeout.call(myArray, myArray.myMethod, 1000); setTimeout.call(myArray, myArray.myMethod, 1500, 2);
上面代码的另外一点不足之处,就是原setTimeout的“指针”没有保存到return function (code, delay) {//这才是真正的overrideFn
这行代码后的数据中,不过考虑JS也不是原生支持OO,这点缺憾还是可以接受的!
现在,我要重点说说setTimeout的超时调用,特别是在循环中
while (!flag) { //等待异步完成==>代码意图:每30毫秒轮询异步完成标志,未完成则等待,让出执行权响应用户事件,意图实现类似sleep效果 setTimeout(null, 30); }
所以,这就是段死循环,不停的创建超时计时器,其它代码没法变更完成标志!一二分钟后就挂了!解决方法,就是回调!
可以用定时器setInterval在回调函数中轮询异步完成标志。但最好的办法还是在异步操作中设置好回调!JS也就这点令人烦,有时大量的回调嵌套三四层,这样OO代码实现就有点烦琐了!
最后点一下,JS引擎单线程,队列式执行:
setTimeout(fn, 0);//fn不会马上执行,而是得先前的执行队列完成才能执行
HTML5中规定:setTimeout最少超时4ms
参考资料:
http://mao.li/javascript/javascript-settimeout-params/
https://developer.mozilla.org/zh-CN/docs/DOM/window.setTimeout
JavaScript: 再论setTimeout、setInterval。其第三个参数和this的讨论,超时嵌套和内存泄漏
标签:
原文地址:http://blog.csdn.net/king_xing/article/details/43268541