今天遇到了这样一个问题,下面有相关源码解析,相关代码在最底下。在setInterval中使用this出现了问题。当间隔时间到达的时候,auto.apply(this);会自动运行,这个时候,this,呵呵,初学者,包括我当初也认为是当前的一个实例。其实,当一运行,就发现一切不是这样了。clear()与auto()方法中,都引用了当前对象的属性,所以,当运行到这些行,this.xxx(如:this.time) 的值都是undefined了,这个可以通过firebug来调试观察到。
实际上,这个查看了相关资料(不好意思,我不记得在哪查的呢,呵呵),结合自己上面调试观察,是这样的。
setTimeout 或 setInterval 的function 中调用其他方法(例如clear与auto) 运行,在调用之时,这些方法会依附上window对象,相当于是window一个属性,所以这些方法里面的 this代表就是window对象。
下面图是在Chrome 的调试工具下截取的 :
实际上,我再进行了一次测试,证明了setTimeout 或 setInterval 中 被调用的方法(例如上图的k),依附了window,形成了一个闭包。
测试方法:先让变量 i 在六秒自加两次,在第七秒,显示一下 变量 i 的当前值 ,结果是 3 。
下面图是在Chrome 的调试工具下截取的 :
2. this 与 setTimeout setInterval,被调的是原型方法
即使是原型自身的方法,this也不是指向当前对象,而是window对象。
下面图是在Chrome 的调试工具下截取的 :
3. this与setTimeout setInterval问题,这种解决方式
这种方式的解决方式,就是定义的方法里面 把this 赋值给一个变量,利用变量来传当前对象。
例如:下面的var self = this
autoScroll : function(second){ var self = this; second = second ? second*1000 : 5000; setInterval(function(){ auto.apply(self); },second);}
其实,这种用法很多,Jquery、Prototype等库中,都有用到,只是平时没注意观察罢了。
4. 最下面的组件,还有一点不得不提及的,虽然与主题不同的----apply方法调用
就是对于apply方法的运用,以前不理解,确实不太理解,干嘛不直接调用,象这种形式:obj.foo(),但是现在能体会到一点点强大之处了。
象clear()、auto(),我都是作为私有方法的,但是里面又不得不调用私有变量,如:this.num,所以只能在运行时,当前对象把clear()、auto()拉
进来调用,但clear()、auto()里面又要用上当前对象的私有变量,这样就必须用上apply方法。
我一直想创建自己的博客,今天做了第一次,呵呵。
1 其实,这组件还很不足,还需要进一步优化扩展,版本还是1.0的。 2 /* 3 #wrapper_sp{height:222px;width: 170px;position:relative;z-index:1;clear:both;margin:4px 0 0 0;} 4 #wrapper_sp .bound{height:225px;width: 170px;} 5 #wrapper_sp .scroll_s{position:absolute;height:20px;width: 170px;display:block;bottom:0;left:0;z-index:2;} 6 #wrapper_sp .bound a{height:225px;width: 170px;display: block;} 7 #wrapper_sp .bound a img{height:225px;width: 170px;border:0;} 8 #wrapper_sp .cpages{height:15px;float: right;margin:1px 0 0 5px;} 9 #wrapper_sp .cpages a.shover{background: #ff0;color:#FF0101;filter:alpha(opacity=80);-moz-opacity:0.8;-khtml-opacity: 0.8;opacity:0.8;} 10 #wrapper_sp .cpages a{float:left;height:14px;width:15px;background: #000;border:1px solid #ccc;margin:0 5px 0 0;color:#FFF; text-align:center; text-decoration:none;filter:alpha(opacity=50);-moz-opacity:0.5;-khtml-opacity: 0.5;opacity:0.5;} 11 */ 12 /** 13 * @function 单个图片轮换效果 14 * @version 1.0 15 * @author zhangwang 16 * @note 程序入口 m_scroll_pic.init(images,links,second,num,initImg,initLink); 17 */ 18 19 var m_scroll_pic = (function(){ 20 var parentN = null;//img节点 21 var linkN = null;//整个容器 22 /** 23 * @author zhangwang 24 * @function 清楚前一个节点的样式 25 * @version 1.0 26 */ 27 function clear(){ 28 var elem = document.getElementById('bhover_0' + this.pre); 29 elem.className = ''; 30 } 31 /** 32 * @author zhangwang 33 * @function 设置轮换节点样式以及图片节点的链接 34 * @version 1.0 35 */ 36 function auto(){ 37 clear.apply(this); 38 this.pre = this.time; 39 linkN.setAttribute('src',this.arr[this.time - 1]); 40 parentN.setAttribute('href',this.arrLinks[this.time - 1]); 41 elem = document.getElementById('bhover_0' + this.time++); 42 elem.className = 'shover'; 43 if(this.time > this.num){ 44 this.time = 1; 45 } 46 } 47 /** 48 * @author zhangwang 49 * @function 图片滚动的构造函数 50 * @version 1.0 51 */ 52 function m_scroll_pic(){//构造函数 53 this.num = 4;//总图片个数 54 this.time = 1;//当前在数组linkN第几个数值 55 this.pre = 1;//保留当前第几个数值的记录 56 this.arr = [];//图片地址 57 this.arrLinks = [];//图片链接 58 } 59 /** 60 * @author zhangwang 61 * @function 图片滚动的原型 62 * @version 1.0 63 */ 64 m_scroll_pic.prototype = { 65 /** 66 * @author zhangwang 67 * @function 设置轮转时间 68 * @param second 轮转间隔时间 69 * @version 1.0 70 */ 71 autoScroll : function(second){ 72 var self = this; 73 second = second ? second*1000 : 5000; 74 setInterval(function(){ 75 auto.apply(self); 76 },second); 77 }, 78 /** 79 * @author zhangwang 80 * @function 每次轮转更换图片以及点击图片链接和右下角 81 * @param j 当前轮转图片的记录数 82 * @version 1.0 83 */ 84 changeImage : function(j){ 85 self = this; 86 clear.apply(self); 87 this.time = j; 88 this.pre = this.time; 89 linkN.setAttribute('src',this.arr[this.time - 1]); 90 parentN.setAttribute('href',this.arrLinks[this.time - 1]); 91 elem = document.getElementById('bhover_0' + j); 92 elem.className = 'shover'; 93 }, 94 /** 95 * @author zhangwang 96 * @function 设置点击图片链接 97 * @param images 图片链接 98 * @version 1.0 99 */ 100 setImages:function(images){ 101 if(!arguments[0]){throw new Error();} 102 if(typeof images == 'string'){ 103 this.arr = images.split(','); 104 }if(Object.prototype.toString.call(images) === '[object Array]'){ 105 this.arr = images; 106 } 107 }, 108 /** 109 * @author zhangwang 110 * @function 设置点击图片的链接 111 * @param links 链接参数 112 * @version 1.0 113 */ 114 setLinks : function(links){ 115 if(!arguments[0]){throw new Error();} 116 if(typeof links == 'string'){ 117 this.arrLinks = links.split(','); 118 }if(Object.prototype.toString.call(links) === '[object Array]'){ 119 this.arrLinks = links; 120 } 121 }, 122 /** 123 * @author zhangwang 124 * @function 设置图片总数量 125 * @param num 图片总数量 126 * @version 1.0 127 */ 128 setnum : function(num){ 129 this.num = num; 130 }, 131 /** 132 * @author zhangwang 133 * @function 轮转图片结构 134 * @param num 设置图片数量 135 * @param initImg 默认放的第一张图片 136 * @param length 轮转图片总数 137 * @version 1.0 138 */ 139 createTree : function(imgSrc,linkUrl,length){ 140 var wrapper = document.getElementById('wrapper_sp'); 141 var bound = document.createElement('div'); 142 var scroll_s = document.createElement('div'); 143 var clear = document.createElement('div'); 144 var cpages = document.createElement('span'); 145 var a = document.createElement('a'); 146 var img = document.createElement('img'); 147 148 img.setAttribute('src',imgSrc); 149 img.setAttribute('id','ahover_01'); 150 a.setAttribute('href',linkUrl); 151 a.setAttribute('target','_blank'); 152 bound.className = 'bound'; 153 scroll_s.className = 'scroll_s'; 154 cpages.className = 'cpages'; 155 clear.style.clear = 'both'; 156 157 wrapper.appendChild(scroll_s); 158 wrapper.appendChild(bound); 159 bound.appendChild(a); 160 a.appendChild(img); 161 scroll_s.appendChild(cpages); 162 wrapper.appendChild(clear); 163 164 for(var i = 1;i <= length;i++){165 var link = document.createElement('a');166 link.setAttribute('id','bhover_0' + i);167 link.setAttribute('href','javascript:sp.changeImage(' + i + ')');168 if(i == 1){169 link.className = 'shover';170 }171 cpages.appendChild(link);172 link.appendChild(document.createTextNode(i));173 }174 parentN = a;175 linkN = img;176 },177 /**178 * @author zhangwang179 * @function initializete picture scroll component180 * @param images picture link181 * @param links after hit picture link182 * @param second 每X秒轮换一次图片,参数3,就是3秒183 * @param num 设置图片数量184 * @param initImg 默认放的第一张图片185 * @param initLink 点击默认第一张图片链接地址186 * @version 1.0187 */188 init : function(images,links,second,num,initImg,initLink){189 if(arguments.length != 6){190 throw new Error('参数不符合要求,请参考API!');191 }192 this.setnum(num);193 this.createTree(initImg,initLink,this.num);194 this.setImages(images);195 this.setLinks(links);196 this.autoScroll(second);197 }198 }199 m_scroll_pic.prototype.constructor = m_scroll_pic;200 return {201 getInstance : function(){202 return new m_scroll_pic();203 }204 }205 }206 )(); 207转载于:https://www.cnblogs.com/zhangwangcai/archive/2011/07/01/2095971.html
相关资源:Javascript对象中关于setTimeout和setInterval的this介绍