mui.pushToRefresh組件下拉回調函數中this指向問題


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



 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM