2010-02-15 42 views
20

我有這樣的代碼:訪問外「這個」在Javascript中的排序方法

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封閉外部物體。

怎麼辦?感謝

回答

29

不同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]; 
     }); 
    } 
} 
+5

感謝,但是這是在Javascript中所接受的方法?坦率地看起來像醜陋的黑客:-) – zaharpopov

+0

也爲什麼你說「do_something」創建關閉?如果我在do_somethiing中打印'this',我會得到正確的對象 – zaharpopov

+2

不,它根本就不是黑客。唯一的另一種方法是通過綁定到該函數來專門設置「this」的含義。但是,在這種情況下,'arr.sort'方法會調用,而您沒有機會設置「this」的含義。在類似於場景的對象中,我實際上在頂部聲明瞭'var base = this;',然後只使用'base'在函數範圍內引用該對象。這樣,我不必猜測何時使用'this'和什麼時候使用'base'。 –

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); 
    ... 
1

您可以斌d通過在內部函數上調用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()