日期:2014-05-16 浏览次数:20540 次
javaScript会在调用时会设置执行上下文“this”的值。
我们举一个例子,给一个Menu构造函数,来接受一个元素来创建一个菜单。
function Menu(elem){
    //...
}
//使用
var elem = document.getElementById('something') // a DOM element
var menu = new Menu(elem);
当我们在构造函数里调用setTimeout时,你也许想引用这个menu对象,我们可能会像如下这样做:
function Menu(elem){
    setTimeout(function(){
        alert(this);    //window, not menu!
    }, 1000);
}
new Menu(document.createElement('div'));
但是this指向的是window,因为setTimeout总是在window上下文环境中执行,再看下面的例子:
function Menu(elem){
    elem.onclick = function(){
        alert(this);    //elem, not menu!
    }
} 元素事件处理器将this设置为指向elem而不是menu。私有方法或本地函数:本地函数经常被用来作为私有方法。
function Menu(elem){
    function privateMethod(){
        alert(this);    //window,not menu!
    }
    //调用私有方法
    privateMethod();
}
new Menu(document.createElement('div'));
调用私有方法,this也是指向window。
首先,我们可以在闭包中存储this。
下面的例子中,将this赋值给self,用self来代替this的使用。
function Menu(elem){
    var self = this;
    setTimeout(function(){
        alert(self);    //object, menu!
    }, 1000);
}
new Menu(document.createElement('div'));
我们需要用到一个帮助函数bind来强制绑定到this。
function bind(func, fixThis){
    return function(){
        return func.apply(fixThis, arguments);
    }
}
function Menu(elem){
    elem.onclick = bind(function(){
        alert(this);    //object!(menu) 
    },this);
}
Function.prototype.bind = Function.prototype.bind || function(fixThis){
    var func = this;
    return function(){
        return func.apply(fixThis, arguments);
    }
}可能有些人觉得这样做污染了原生的属性,不推荐这种用法。但是改变Function.prototype有时也是能够接受的。它不会影响对象或数组的迭代,副作用非常小的。
如果用上面这种方法,那会简单很多。
setTimeout
function Menu(elem) {
 
  setTimeout(function() {