我有这段代码:
function some_object(...) {
this.data = {...};
this.do_something = function(...) {
var arr = [...];
arr.sort(function (a, b) {
return this.data[a] - this.data[b];
});
}
}
但是我认为它不起作用,因为this
无法访问sort
- 由于某种原因,可以看到另一个this
,而不是封闭外部对象的this
。
怎么办?感谢
答案 0 :(得分:33)
不同的this
是因为arr.sort
调用的匿名函数(它自己的闭包)调用函数,this
被设置为与主对象不同的项。在Array.sort中,我实际上并不确定this
的设置是什么,但它可能是您要排序的数组。在这种情况下正常的解决方法是使用另一个变量:
function some_object(...) {
var so = this; // so = current `this`
this.data = {...};
this.do_something = function(...) {
var arr = [...];
arr.sort(function (a, b) {
return so.data[a] - so.data[b];
});
}
}
答案 1 :(得分:7)
您可以通过在内部函数上调用bind
方法将“外部”实例绑定到“内部”函数。请访问MDN了解详情。
示例:https://jsfiddle.net/eheobo/twv3emh7/1/
var foo = {
data: [1, 2, 3, 4],
bar: function () {
var printData = function(){
this.data.forEach(a => console.info(a))
}.bind(this)
printData()
}
}
foo.bar()
答案 2 :(得分:2)
我知道这是2010年以来的一个问题,但是现在您可能应该使用箭头函数(和类):
class some_object {
constructor() {
this.data = {...};
}
do_something(...) {
let arr = [...];
arr.sort((a, b) => this.data[a] - this.data[b]);
}
}
箭头函数没有this
,因此它们使用封闭范围中的那个。
答案 3 :(得分:0)
由于您的排序算法不依赖do_something
内的任何内容(除了数组提供的内容),请考虑将函数移到do_something
之外:
function some_object(...) {
var so = this;
so.data = {...};
var comparator = function(a,b) { return so.data[a] - so.data[b]; };
this.do_something = function(...) {
var arr = [...].sort(comparator);
}
}
或者,如果你在其他地方进行这种分类,甚至提供一个简单的工厂:
var comparatorFactory = function(data) { return function(a,b) { return data[a] - data[b]; } };
function some_object(...) {
var so = this;
so.data = {...};
var comparator = comparatorFactory(so.data);
...