先看一段代碼
(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實例對象了。