2013-11-22 72 views
0

我有我想要的,這將在以後的時間被調用函數中使用的變量。這裏的情況:傳遞價值函數被調用後

var a = 'something'; 

var mapFun = { 
    map: function (doc) { 
     if(doc.a === a) { 
      emit(doc, doc); 
     } 
    } 
}; 

所以map()是一家被在不同的上下文調用以後的功能。所以當函數被調用時,a是未定義的。這是有道理的,但我想知道我怎麼能在函數內部訪問的a值。例如:

if(doc.a === a)應該if(doc.a === 'something')當函數被調用。

編輯:我理解我設置示例的方式,使其看起來好像a是一個全局變量。不是這種情況。內mapFunmap()方法被調用不訪問a

+1

你是什麼意思「不同的環境?」它的寫法是''a''是全球性的,並且應該在以後提供。 – Jeff

+0

我的意思是,對象'mapFun()'被傳入一個超出此範圍的函數。完全分開。它無法訪問'a' –

+0

這應該已經可以工作,因爲'a'可以在與mapFun相同的範圍內使用 –

回答

1

如果a不再作用域時調用此函數在不同的情況下,嘗試把它在窗口中進行a全局函數裏面。取而代之的var a = 'something';window.a = 'something';

+0

這個作品!不知道這是否是理想的解決方案,但它的工作原理!謝謝 –

+1

將變量放在全局範圍內,以便您可以訪問它們是一種反模式。首先,您將創建太多可能被其他代碼覆蓋的變量,其次,如果您有多個需要多個「a」值的實例,則需要編寫更復雜的代碼才能訪問它們。要麼mapFun或其他對象記住a的值,要麼將一個閉包傳遞給庫,該庫調用mapFun.map傳遞閉包。 – HMR

+0

@HMR我同意,由於信息不足,破譯OP最終要做的事情有些困難。這絕對是一個拙劣的解決方案。不知道你需要發表這個評論4次雖然:) – NaNpx

1

嘗試,而不是做var a = "something";,嘗試做window.a = "something";,然後通過做if(doc.a == window.a)你的代碼中引用它。
如果不工作,我不知道是什麼會。
祝你好運!

+1

將變量放在全局範圍內,以便您可以訪問它們是一種反模式。首先,您將創建太多可能被其他代碼覆蓋的變量,其次,如果您有多個需要多個「a」值的實例,則需要編寫更復雜的代碼才能訪問它們。要麼mapFun或其他對象記住a的值,要麼將一個閉包傳遞給庫,該庫調用mapFun.map傳遞閉包。 – HMR

1

如果你試圖訪問另一個函數的範圍內定義的變量,你需要,無論是通過將其存儲在全局範圍內或在全球將它添加到一個對象的原型解除從範圍變量範圍(IE是你試圖傳遞「a」到的對象)。

例如:

var mapFun = { 
    map: function(){ 
     //do something here 
     alert(this.a); 
    } 
}; 

mapFun.a = "something"; 

看到這是如何工作的:http://jsfiddle.net/z8Uvr/

+1

將變量放入全局範圍,以便您可以訪問它們是一種反模式。首先,您將創建太多可能被其他代碼覆蓋的變量,其次,如果您有多個需要多個「a」值的實例,則需要編寫更復雜的代碼才能訪問它們。要麼mapFun或其他對象記住a的值,要麼將一個閉包傳遞給庫,該庫調用mapFun.map傳遞閉包。 +1至少添加一個替代品。我在答案中也添加了閉包。 – HMR

0

變量amapFun在同一個範圍內,所以他們一般應始終可用對方。

即使.map()函數被調用另一個函數,其中被宣佈爲函數內仍然可以訪問a

當你創建一個新的範圍,你在該範圍內創建的所有變量和函數使用的功能和在相同範圍內創建的對象。

如果您有訪問0​​你可以把一個問題是提供給窗口(全局)對象說window.a = 'something';

添加a在全球範圍內,因爲它可能會引起衝突時要小心。

感謝@HMR指出了這一點

+1

將變量放在全局範圍內,以便您可以訪問它們是一種反模式。首先,您將創建太多可能被其他代碼覆蓋的變量,其次,如果您有多個需要多個「a」值的實例,則需要編寫更復雜的代碼才能訪問它們。要麼mapFun或其他對象記住a的值,要麼將一個閉包傳遞給庫,該庫調用mapFun.map傳遞閉包。 – HMR

+0

@HMR +1:用於警告與'window'聲明'a'的衝突。編輯回答表明可能的問題。 –

3

把變量在全局範圍內,所以你將有機會獲得它以後在任何語言中的反模式。我很驚訝所有來自JavaScript程序員的4個答案都會建議做這樣的事情。

比方說,你需要mapFun.map傳遞給someLib.callBack,你打發時間的地圖,你知道的價值因此,你可以使用閉包:

var a = 22; 
someLib.callBack = function(doc){ 
    mapFun.map(doc,a); 
}; 

它會看起來好像someLib會傳遞「a」,但它只會傳遞「doc」。如果稍後必須更改「a」的值,則取決於範圍。如果a被傳遞,那麼重新分配它不會改變它,所以你需要傳遞一個可以被突變的對象。

var someLib = { 
    callBack : function(fn){ 
    setTimeout(function(){ 
     fn("hello"); 
    },100); 
    } 
}; 
var mapFun = { 
    map : function(doc,a){ 
    console.log("doc passed when called:",doc); 
    console.log("variable a is:",a); 
    } 
}; 
(function(){ 
    var a = 22; 
    someLib.callBack(function(doc){ 
    mapFun.map(doc,a); 
    }); 
    a=44;//this is fine, same scope 

    a=22; 
    someLib.callBack(function(doc){ 
    mapFun.map(doc,a); 
    }); 
    (function(a){ 
    a = "not changed"; 
    }(a));//doesn't change a because you assign it in a different scope 

    var obj={}; 
    obj.a=22; 
    someLib.callBack(function(doc){ 
    mapFun.map(doc,obj.a); 
    }); 
    (function(obj){ 
    obj.a = "Hello World"; 
    }(obj));//changed a because you mutated the object 
    //diffeerent scope doesn't matter here. 
}()); 

如果關閉不是一個選項,你可以讓我的地圖記住一個由Trendy建議的值。

+0

+1我正在寫一個類似的答案,使用對象屬性而不是字符串。 – Christophe

+0

@Christophe謝謝你,我很驚訝沒有人加入了將變量「a」作爲模塊範圍的範圍,並將mapFun放在IIFE中(function(){var moduleGlobalA,mapFun = {};}());'' – HMR