简体   繁体   English

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

[英]How to invoke outer “this” in inner function?

I defined two functions for array: 我为数组定义了两个函数:

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!!
    });
}

But in the removeAll function, it reports function remove is not found . 但是在removeAll函数中,它function remove is not found I fix it like this: 我修复它像这样:

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

But it's ugly. 但它很难看。 Is there a better way? 有没有更好的办法?

Passing this via a different variable as you do is the idiomatic approach. 通过一个不同的变量传递this是惯用的方法。 There is nothing ugly about it. 它没什么难看的。 (It is more common to call the variable that or self though) (这是比较常见的调用变量thatself虽然)

By passing next one argument to forEach which will be context of this in callback function, In your case this refers to window object. 通过传递下一个参数的forEach这将是上下文this在回调函数,你的情况, this指的是window对象。

Array.prototype.removeAll = function(array2) {

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

An alternative to using bind (if you need to support old browsers and don't wish to extend Function.prototype ) is to simply wrap your callback in an immidate function and feed this in as an argument like this: 使用bind的替代方法(如果你需要支持旧的浏览器并且不希望扩展Function.prototype )就是简单地将你的回调包装在一个immidate函数中,并将this作为参数提供给这样:

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

or you can write a simple curry utility function and use like 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));
}

If you don't mind extending Function.prototype you can use bind as already described by others you can find an excellent compatibility extension on MDN here: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind 如果您不介意扩展Function.prototype您可以使用其他人已经描述过的bind,您可以在MDN上找到一个出色的兼容性扩展: https//developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/捆绑

There is Function.bind and similar. Function.bind和类似的。

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

It's not technically the same, as the previous the "inner this" is now shadowed/lost (and a new wrapper function is created), but it works nicely in some contexts. 它在技术上并不相同,因为之前的“内部this”现在被阴影/丢失(并且创建了一个新的包装器函数),但它在某些情况下很好地工作。

For the most part, I prefer the standard var self = this ... 在大多数情况下,我更喜欢标准var self = this ...

Happy coding. 快乐的编码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM