被这个this指向弄晕了,求请教

    function Router(){
        this.routes = {};
        this.currentUrl = '';
    }
    Router.prototype.route = function(path, callback){
        this.routes[path] = callback || function(){};
    }
    Router.prototype.refresh = function(){
        this.currentUrl = location.hash.slice('1') || '/';
        this.routes[this.currentUrl]();
    }
    Router.prototype.init = function () {
        window.addEventListener('load', this.refresh.bind(this), false);
        window.addEventListener('hashchange', this.refresh.bind(this), false);
    }
    window.Router = new Router();
    window.Router.init();

    var content = document.querySelector('body');
    // change Page anything
    function changeBgColor(color) {
        content.style.backgroundColor = color;
    }
    Router.route('/', function () {
        changeBgColor('red') 
    })
    Router.route('/blue', function () {
        changeBgColor('blue') 
    })
    Router.route('/green', function () {
        changeBgColor('green') 
    })
    
    
    
    

问题就在于 window.addEventListener('load', this.refresh.bind(this), false);
这句话中 this.refresh.bind(this),弄晕了, 换成this.refresh.apply(this)和 call 都会报错, 有人能帮我来理清这个this指向的顺序吗?以及为什么不能使用 apply和call

阅读 2.7k
3 个回答

this.refresh.apply(this)
是改变作用域并执行
this.refresh.bind(this)
是改变作用域并返回新函数(未执行)
这里的this.refresh.bind(this)是改变addEventListener的this将其指向Router,因为事件的this指向事件的绑定者,这里是window

call和apply会自动执行函数,而bind不会

window.addEventListener里的第二个参数是一个函数

用call和apply的话得到的就是执行完的结果,也就是函数返回值,你的refresh没有返回值(return),得到的也就是undefined,所以会报错啦

apply,call改变函数中this的指向,就相当于给对象添加了一个属性,
而bind它改变函数中this的指向,是创建了一个函数,内部实现了apply的作用,但是它返回的是个函数,你可以在addEventListener中当回调函数使用,而前者没有这个作用,所以会报错。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题