2016-08-18 42 views
0

好的,我不認爲在C#中這樣做,但是JavaScript的設計具有更多的訪問靈活性。在javascript中爲第三方封閉添加一個函數

有這樣

(function($) 
{ 
    ...more stuff 
    var results={a:1,b:2} //this I need to modify 
    var someData={x:1} 
    send = function(){ 
     //send results ajax 
    }; 

    if(typeof beforeSend=='function') 
     beforeSend(someData) //hook to use results 
})(jQuery) 

所以一個插件,在我自己的代碼,我具備的功能window.beforeSend = function(d){}

,它確實有someData這是我需要修改的範圍。但這裏有一個問題: 我該如何修改結果變種,它是在它發送它之前的封閉。 我需要添加

window.beforeSend = function(d){ 
    window.quantumTunnelThroughScope.results['c']=1 
} 

的原因,我需要做的,這是因爲我不能修改該插件的代碼。當然,如果我在閉包中添加beforeSend,它可以工作,但是我正在修改這種情況下我不允許執行的庫。

我見過一些很棒的eval('this.xx'= function)等等,但我無法讓它工作。

編輯:我澄清,實際上它是在需要進行編輯

+0

全局變量? – mathiasfk

+0

@TJCrowder很好,因爲我需要在結果發送之前添加c = 1 – AwokeKnowing

+0

@TJCrowder是的,我很抱歉,我將代碼縮減爲本質,但通過在示例 – AwokeKnowing

回答

1

不相同的範圍內不同的變種,有一個爲beforeSend達到成關閉和修改results沒有合理方式。所提供的代碼中的results對該閉包內的代碼完全是私有的。

不合理方式嘗試這樣做是反編譯和重新編譯的插件功能,通過evalbeforeSend,讓我們前插入一個調用的函數修改results

(function($) { 
 
    $.run = function() { 
 
    // You mentioned "ajax," so let's make this 
 
    // asynchronous 
 
    setTimeout(function() { 
 
     var results = { 
 
     a: 1, 
 
     b: 2 
 
     }; 
 
     var someData = { // Need to modify this 
 
     x: 1 
 
     }; 
 
     send = function() { 
 
     //send results ajax 
 
     }; 
 

 
     if (typeof beforeSend == 'function') { 
 
     beforeSend(someData); //hook to use results 
 
     } 
 

 
     console.log("in plugin, results = ", results); 
 
    }, 10); 
 
    }; 
 
})(jQuery) 
 

 
window.modifyResults = function(d) { 
 
    return ["new", "results"]; 
 
}; 
 
window.beforeSend = function(r) { 
 
    r.c = 1; 
 
}; 
 

 
jQuery.run = (function() { 
 
    // Function#toString, on nearly all browsers, returns the source 
 
    // code of he function (or something near to it) except on functions 
 
    // implemented in native code. We take that string and replace 
 
    // the "beforeSend(someData);" call with two calls, the first of 
 
    // which lets us modify the `results` variable. Then we use eval 
 
    // to turn that back into a function, and assign the result to 
 
    // where the plugin put its function originally. 
 
    return eval("(" + jQuery.run.toString().replace(
 
    "beforeSend(someData);", 
 
    "results = modifyResults(results); beforeSend(someData);" 
 
) + ")"); 
 
})(); 
 

 
jQuery.run();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

但可能會或可能無法正常工作,這取決於插件是怎麼寫的,因爲它提升它原來的範圍,並重新編譯它我們的功能更新範圍爲jQuery.run

我想我寧願去修改插件。 :-)


注意:在上面,我用了一個「靜態」jQuery函數。如果您要替換的插件提供了實例函數,那麼您可以在jQuery實例上調用該類型,例如在$(".foo").bar()bar,你會發現它jQuery.fn而不是jQuery

jQuery.fn.pluginFunction = eval(...); 
+0

我很抱歉它是不清楚,但通過「之前」我只是指在實際發送功能之前運行的beforeSend掛鉤。那beforeSend鉤子實際上是在閉包的代碼中,並且在發送之前已經被調用,所以在我自己的代碼中,如果我把魔術範圍修改代碼放在那個鉤子函數中,它會在發送前運行 – AwokeKnowing

+0

另外,我覺得因爲我可以看到對象,如果我瀏覽jquery對象,我應該可以在代碼中以某種方式訪問​​它。 – AwokeKnowing

+0

另外,如果我可以將自己的函數注入到作用域本身,那麼它當然可以訪問變量 – AwokeKnowing