如何在内部函数中调用外部“this”?

时间:2011-12-23 09:26:00

标签: javascript function

我为数组定义了两个函数:

Array.prototype.remove = function(obj) {
    var i = this.length;
    while (i--) {
        if (this[i] === obj) {
            this.removeAt(i);
        }
    }
};
Array.prototype.removeAll = function(array2) {
    array2.forEach(function(item) {
        this.remove(item);  // remove not found!!
    });
}

但在removeAll函数中,它会报告function remove is not found。我这样解决了:

Array.prototype.removeAll = function(array2) {
    var outer = this;
    array2.forEach(function(item) {
        outer.remove(item);  
    });
}

但它很难看。还有更好的方法吗?

4 个答案:

答案 0 :(得分:6)

通过不同的变量传递this就像惯用法一样。它没什么难看的。 (更常见的是调用变量thatself

答案 1 :(得分:2)

通过将下一个参数传递给forEach,它将成为回调函数中this的上下文,在您的情况下this引用窗口对象。

Array.prototype.removeAll = function(array2) {

    array2.forEach(function(item) {
        this.remove(item);  
    },this);
}

答案 2 :(得分:2)

使用bind的替代方法(如果您需要支持旧浏览器并且不希望扩展Function.prototype)是简单地将回调包装在一个immidate函数中并将this作为参数提供像这样:

Array.prototype.removeAll = function(array2) {
    array2.forEach(function(outer){
     return function(item) {
        outer.remove(item);  
    };}(this));
}

或者你可以写一个简单的咖喱效用函数并像这样使用

function curry() {
  var fn = Array.prototype.shift.call(arguments), 
      args = Array.prototype.slice.call(arguments);
  return function curryed() {
    return fn.apply(this, args.concat(Array.prototype.slice.call(arguments)));
  };
};



Array.prototype.removeAll = function(array2) {
    array2.forEach(curry(function(item) {
        outer.remove(item);  
    },this));
}

如果你不介意扩展Function.prototype,你可以使用其他人已经描述的绑定,你可以在MDN上找到一个出色的兼容性扩展:https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind

答案 3 :(得分:1)

Function.bind和类似。

array2.forEach((function(item) {
    this.remove(item);  
}).bind(this));

它在技术上并不相同,因为之前的“内部this”现在被遮蔽/丢失(并且创建了 new 包装函数),但它在某些情况下运行良好。

在大多数情况下,我更喜欢标准var self = this ...

快乐的编码。