先看一段代码
(function($) { //阻尼系数 var deceleration = mui.os.ios ? 0.003 : 0.0009; $('.mui-scroll-wrapper').scroll({ bounce: false, indicators: true, //是否显示滚动条 deceleration: deceleration }); var up, down; $.ready(function() { //循环初始化所有下拉刷新,上拉加载。 $.each(document.querySelectorAll('.mui-slider-group .mui-scroll'), function(index, pullRefreshEl) { $(pullRefreshEl).pullToRefresh({ down: { callback: function() { var self = this; down = self; setTimeout(function() { var ul = self.element.querySelector('.mui-table-view'); ul.insertBefore(createFragment(ul, index, 10, true), ul.firstChild); self.endPullDownToRefresh(); }, 1000); } }, up: { callback: function() { var self = this; up = self; console.log(up === down); setTimeout(function() { var ul = self.element.querySelector('.mui-table-view'); ul.appendChild(createFragment(ul, index, 5)); self.endPullUpToRefresh(); }, 1000); } } }); }); var createFragment = function(ul, index, count, reverse) { var length = ul.querySelectorAll('li').length; var fragment = document.createDocumentFragment(); var li; for (var i = 0; i < count; i++) { li = document.createElement('li'); li.className = 'mui-table-view-cell'; li.innerHTML = '第' + (index + 1) + '个选项卡子项-' + (length + (reverse ? (count - i) : (i + 1))); fragment.appendChild(li); } return fragment; }; });})(mui);
上面代码30行我测试了一下down和up中的this是否引用了同一个对象,返回结果如下:
疑惑。。。
根据js词法作用域推断,up对象callback方法中this应该引用的是up对象,down 对象callback方法中this应该引用的是down对象
为什么会引用同一个对象呢?
为了验证我的推断,写了如下测试代码:
var o = Object.create({ id: 1, name: 'tom' });o.age = 19;console.log(o);o.print = function(obj) { Object.assign(obj, o); console.log(JSON.stringify(obj)); obj.up.callbackup(); obj.down.callbackdown();}o.print({ up: { callbackup() { upCb(this); } }, down: { callbackdown() { downCb(this); } }});
调试过程查看this引用的对象:
结果完全符合我的推断
查看了mui.pushToRefresh.js,找到了答案:
pullDownLoading: function() { if (this.loading) { return; } if (!this.pullDownTips && this.options.down.pullDownTipStyle === 'pullDownTips') { this.initPullDownTips(); this.dragEndAfterChangeOffset(true); return; } else { scroll.scrollTo(0, 40, 100); scroll.stopped = true; } this.loading = true; this.addMask(); if (this.pullDownTips && this.options.down.pullDownTipStyle === 'pullDownTips') { this.pullDownTips.classList.add(CLASS_TRANSITIONING); this.pullDownTips.style.webkitTransform = 'translate3d(0,' + this.options.down.height + 'px,0)'; } else { var topTipIcon = document.getElementById('topTipIcon'); topTipIcon.className = 'mui-pull-loading mui-icon mui-spinner'; topTipIcon.style.webkitAnimation = 'spinner-spin 1s step-end infinite'; document.getElementById('topTipText').innerText = '正在刷新...'; } this.options.down.callback.apply(this);}
第26行,尽管js中变量的作用域是定义时就确定了的,但是可以使用aplly, call等方法在运行时改变方法的上下文对象,从而可以解释本文开头的疑惑了。
执行callback的时候,this被重定向到pushToRefresh实例对象了。