Javascript 如何调用“外部”;这";内在功能?

Javascript 如何调用“外部”;这";内在功能?,javascript,function,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(functio

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

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
函数中,它报告未找到
函数remove
。我这样修理它:

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

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

通过一个不同的变量传递
这是惯用的方法。这没有什么难看的。(更常见的是调用变量
,即
self

存在和类似的变量

array2.forEach((function(item) {
    this.remove(item);  
}).bind(this));
从技术上讲,它与以前的“内部this”不同,现在被隐藏/丢失(并创建了一个新的包装函数),但它在某些上下文中工作得很好

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


快乐编码。

通过在回调函数中传递下一个参数,该参数将是
this
的上下文,在您的例子中
this
引用窗口对象

Array.prototype.removeAll = function(array2) {

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

使用bind的另一种替代方法(如果您需要支持旧浏览器并且不希望扩展
函数.prototype
)是简单地将回调包装在immidate函数中,并将
作为如下参数输入:

Array.prototype.removeAll = function(array2) {
    var outer = this;
    array2.forEach(function(item) {
        outer.remove(item);  
    });
}
Array.prototype.removeAll = function(array2) {
    array2.forEach(function(outer){
     return function(item) {
        outer.remove(item);  
    };}(this));
}
或者您可以编写一个简单的curry实用程序函数并使用如下方式

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
您可以像其他人所描述的那样使用bind,您可以在MDN上找到一个非常好的兼容性扩展:

我认为它不是非常难看,而且可以工作。foreach中的“this”已更改为迭代中的项,因此我看不到太多的解决方法。很好,我不知道。请注意,ie8和早期版本不支持此功能。据我所知,
函数。bind
是ECMAScript 5,只有最新浏览器才支持它(在IE8、FF3.6、FF3.6、Safari 4、Safari 5、Safari 5.1和Opera 10.50-11.50中不受支持)@StefanGehrig您是正确的,因此“和类似的”:-)实现这样的功能很容易,MDC文档提供了这样的示例。在许多框架中都可以找到相同的功能。只想注意这个重要的细节…;-)