2016-07-07 112 views
2

這-方面,我有以下問題:得到正確的功能

我嘗試覆蓋功能與角($scope.$apply())然後應用它,但我this似乎-context不會是正確的一。

原有功能(在另一個文件中),如下所示:

Anno.prototype.switchTo = function(otherAnno) { 
    if (otherAnno != null) { 
     this.hideAnno(); 
     return otherAnno.show(); 
    } else { 
     console.warn("Can't switchTo a null object. Hiding instead."); 
     return this.hide(); 
    } 
}; 

然後在另一個文件I「覆蓋」是這樣的:

var switchToFunction = AnnoModule.Anno.prototype.switchTo; 
AnnoModule.Anno.prototype.switchTo = function(otherAnno) { 
    switchToFunction(otherAnno); 
    $scope.$apply(); 
}; 

所以其實我保存原始函數,然後重新定義原始函數以調用原始函數,然後應用範圍。你可以看到,函數使用this.hideAnno(),但在我重新定義的函數中,上下文是另一個,這就是爲什麼chrome拋出一個錯誤,說「this.hideAnno()不是一個功能」。但是現在我不確定我如何才能找到正確的上下文。我試圖理解this,但是JavaScript很混亂,我真的不明白。

有人能幫我理解JavaScript混淆嗎?

回答

1

當一個函數被調用,如JS的方法,該this它裏面是指在方法屬於對象。另一方面,當函數被自己調用時,其內部的this以嚴格模式引用全局對象或undefined

您正在提取(然後調用)定義爲方法的函數爲獨立函數,這就是爲什麼this不符合您的期望。

你在這種情況下,需要的是callapplyswitchToFunction,創下this到你所需要的價值。換句話說,你把舊法的this是您創建的新方法的this

var switchToFunction = AnnoModule.Anno.prototype.switchTo; 
AnnoModule.Anno.prototype.switchTo = function(otherAnno, that) { 
    switchToFunction.call(this, otherAnno); // sets `this` of the old method to be this of the new method you created 
    $scope.$apply(); 
}; 
+0

工作,謝謝。預計不會那麼容易......我甚至已經嘗試在你所處的位置使用'call'方法,但是我沒有將'this'作爲第一個參數。 – user5638730

+0

很高興幫助:)。是的,'call'或'apply'的唯一目的是在調用一個函數時設置'this'的值,而不是其他的 – nem035

1

要理解這個問題,我認爲首先我們應該瞭解如何this關鍵字作品,以及如何進行調整。

在JavaScript的任何函數的內部的this對象將是對象在其上調用方法

考慮,

var obj1 = { 
    foo: function() { 
     console.log(this); 
    } 
}; 

function bar() { 
    console.log(this); 
} 

現在,當調用方法,我們得到的輸出象下面,

obj1.foo();  // obj1 
bar();   // window 

因爲foo方法上obj1調用,所以this內這些下面的例子foo方法變爲obj1。同樣this裏面的bar方法將是window對象。現在

,如果我想要什麼調用barobj1作爲this裏面的功能。對於這個JavaScript提供了call, apply and bind方法來動態改變函數的this。讓我們看看如何使用call方法來實現這一點。

bar.call(obj1);   // obj1 

同樣,

obj1.foo.call(window);   // window 

call方法採用thisArg對象作爲參數,這將是thisbar函數內。並且如果bar函數也期望參數可以通過thisArg之後通過call方法傳遞。有關call的信息,請參閱MDN

所以對於你的問題的解決方案將是,

var switchToFunction = AnnoModule.Anno.prototype.switchTo; 
AnnoModule.Anno.prototype.switchTo = function(otherAnno) { 
    switchToFunction.call(this, otherAnno); 
    $scope.$apply(); 
}; 

希望這清楚地讓你理解這個問題。