2017-03-25 161 views
0

如果我在函數中創建回調函數,我可以通過回調函數訪問函數中的局部變量嗎?在回調函數內部訪問函數的局部變量

Obj.prototype.outerFunc = function() 
{ 
    var x = 0; 
    var callback = this.innerFunc; 
    callback(); 
} 

Obj.prototype.innerFunc = function() 
{ 
    x++; 
} 

x自然不是innerFunc範圍內,並且如果調用本身將產生錯誤。但是如果我從outerFunc調用它,我可以擴展innerFunc's範圍以訪問x

編輯:應該提到,我不想將參數傳遞到函數或使x和Obj的實例。我更願意將innerFunc視爲在outerFunc的本地宣告。類似於下面的做法:

Obj.prototype.outerFunc = function() 
{ 
    var x = 0; 
    var callback = function() { 
     x++; 
    } 
    callback(); // works 
} 
+0

唯一的方法是如果'outerFunc'將'x'放在共享範圍內。全球範圍是所有功能之間共享的。但是,沒有辦法直接影響被調用者的範圍。基本上你以後稱之爲*動態範圍*。 JavaScript和大多數語言都有*詞法範圍*。 –

回答

2

是的:這正是功能參數的用途。它們允許您將一個範圍的值傳遞給另一個範圍。

Obj.prototype.outerFunc = function() 
{ 
    var x = 0; 
    var callback = this.innerFunc; 
    x = callback(x); 
} 

Obj.prototype.innerFunc = function(x) 
{ 
    x++; 
    return x; 
} 

請注意,該值被髮送到另一個函數,而不是變量。所以你需要返回值並賦值才能使用它。

+0

應該提到,但我試圖避免將x作爲參數傳遞(請參閱我對原始問題所做的編輯) – sookie

+0

@sookie這正是函數應該避免的。 – lonesomeday

0

如果您使用的原型,只是設置實例屬性:

// constructor 
var Obj = function() {} 

Obj.prototype.outerFunc = function() 
{ 
    this.x = 0; 
    var callback = this.innerFunc.bind(this); 
    callback(); 
} 

Obj.prototype.innerFunc = function() 
{ 
    this.x++; 
} 

var instance = new Obj() 
instance.outerFunc() 
console.log(instance.x) // returns 1 

編輯:但@ lonesomeday的答案是一個更好的解決方案,因爲它需要一個功能更強大的方式避免副作用:)

+0

對不起,應該提到,但我實際上試圖避免使x的一個Obj的實例(見編輯我對原始問題) – sookie

0

這樣做的優先停留的方式是對x分配給對象然後所有功能可以訪問它的範圍內,通過this.x

Obj.prototype.outerFunc = function() 
{ 
    this.x= 0; // set x to zero 
    this.innerFunc(); 

} 

Obj.prototype.innerFunc = function(x) 
{ 
    this.x++; 
    return this.x; 
} 
+0

謝謝。實際上,我試圖避免將x作爲Obj的實例(請參閱我對原始問題所做的編輯) – sookie

+0

如果可以在outerFunc中添加原型,那麼x將是可訪問的,或者如果可以使x成爲對象外的全局。 – MartinWebb

0

這有點硬而不knowi解決爲什麼你不想傳遞一個參數;如果你只是想有一個特定的功能簽名,也許更高階的功能可能有幫助?

Obj.prototype.outerFunc = function() 
{ 
    var x = 0; 
    var callback = this.innerFunc(x); 
    callback(); 
} 

Obj.prototype.innerFunc = function(x) 
{ 
    return function() { /* use x in here */ }; 
} 

這樣你就有兩個功能在一個裏面。外部參數接受參數,內部參數可以訪問傳遞給外部參數的變量。

這當然只給你一半你在你的例子中演示:你可以訪問本地變量,但不能修改它。

0

在任何情況下,在OOP上下文中或其他情況下,都不能從函數外部訪問任何函數的內部變量。

唯一的例外是在函數B中定義並從該函數B返回的函數A繼續訪問函數B中的變量 - 閉包的基本概念。

我不知道爲什麼你不想使用實例變量。這就是他們想要的 - 跨方法共享數據。我不知道爲什麼你不想傳入或傳出值 - 這就是參數和返回值。

我可以擴展innerFunc的範圍以訪問x嗎?

不,你不能,無論如何。 JS中沒有這樣的概念。

你可以來你似乎什麼也許想要做的最接近的是在構造函數中定義變量:

function Obj() { 
    var x = 0; 

    this.outerFunc = function() { 
    var callback = this.innerFunc; 
    callback(); 
    }; 

    this.innerFunc = function() { 
    x++; 
    } 
} 

但是,這將無法正常工作,是因爲this.innerFunc缺少它的上下文。因此,你需要寫

var callback =() => this.innerFunc(); 

然而,這是一個謎,你爲什麼會想這樣做,而不是僅僅寫this.innerFunc()