顯示廣告
隱藏 ✕
※ 本文為 dinos.bbs. 轉寄自 ptt.cc 更新時間: 2013-01-20 09:09:09
看板 Ajax
作者 StarTouching (撫星)
標題 Re: [問題] 為何FF無法藉由new Function()傳遞事件?
時間 Sat Jan 19 17:02:45 2013


※ 引述《folio (function(){})()》之銘言:
: - ms dom 中,event 發生時,記載 event data 的 object 放在一個 global variable 裡面,
:   這個 global variable 叫做 event。
: - 而 global variable 其實就是 global object 的某個 property。
: - 當我們討論 client-side 的時候 global object 就是 window object。
: 綜合以上三點,所以 ms dom 中,handler 需要 event data 的時候,會寫 window.event,
: 事實上你寫 event 也是一樣的意思。
: oncilck = Function("if(keyVerify(event)")...)
: 當 Function constructor 被 evaluate 的時候,是在 global scope 中 evaluate,
: 首先在 javascript 裡面如果是要動態產生 function 的話,並不需要用 Function constructor。
: 寫 function(){} 就可以了,理由一是 Function constructor 要把 function body 交給
: interpreter 處理,這是很昂貴的事情;理由二,這製造了 injection 的時機。

其他部份我懂了 先謝謝你的答覆

不過這點我要解釋一下

我使用new Function()是因為有變數傳遞


 function(){toPage(i)}  i的值一律都會變成迴圈最後一圈的值

我猜想這是因為 function() 匿名函式(函式實字) 要一直到被呼叫的時候

才會去抓變數職

所以當onclick觸發時 i的值當然就固定在最後的值


但是用  new Function("toPage("+i+")")  就抓得出來

因為函式建構子在宣告這個函式的當下 就已經在解析變數i。


我後來得知匿名函式另一種方法 這應該才是真正的參數傳遞吧:

                                                                             
  onclick = function(j) {                                                    
          return function(){                                                
                  toPage(j);                                                
          }                                                                  
  }(i);                                                                      
                                                                             

透過這種方式 外面那層函式會被立即呼叫

所以變數當然也會立刻解析。

和上面比起來 優點是他傳遞的是變數 而不是值

所以要傳遞參考變數例如物件 單獨new Function就沒用了

一定要用這種方法。

另外就是 只有外面那層要交給interpreter立即處理

不像函式建構子整個function動作都要丟給 interpreter


雖然如此 我想 new Function 還是有它派上用場的時候。


拿我這次寫的東西舉例:

                                                                             
  function foo(obj, css1, value1, css2, value2)                              
  {                                                                          
          var f = new Function("obj", "v", "obj.style." + css1 + "= v");    
          f(obj, value1);                                                    
          f = new Function("obj", "v", "obj.style." + css2 + "= v");        
          f(obj, value2)                                                    
  }                                                                          
                                                                             

                                                                             
  foo(this, "height", "300px", "width", "500px");                            
                                                                             

因為函式建構子是將字串轉成程式碼

所以彈性就高出許多 原本code不能放變數的地方

透過new Function就能做出變化。

我個人猜想 jQuery可能也是用類似方法實作的。


至於injection漏洞問題 這我確實就不太明白了。

請問可以舉個例子嗎?

這樣以後也好避免。

--
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 1.162.203.164
※ 編輯: StarTouching    來自: 1.162.203.164        (01/19 17:06)
s25g5d4:看起來這東西就像eval阿 jQuery不太可能用這種方式1F 01/19 17:27
s25g5d4:jQuery還真的有用到new Function() 當我沒說好了
StarTouching:對耶 原來eval是這樣用的 我現在才知道 XDDD3F 01/19 17:46
StarTouching:不過既然如此 如果函式建構子有injection問題
StarTouching:eval()也一樣會有
StarTouching:http://ppt.cc/ckf-
s25g5d4:在jQuery裡用到這一段是因為parse JSON 而且它有做valid7F 01/19 17:57
s25g5d4:可以盡量避免掉XSS的問題 eval本來就有這樣的問題沒錯
s25g5d4:基本上現在主要瀏覽器的最新版本都有原生parseJSON
s25g5d4:所以用jQuery遇到new Function的機率幾乎等於零
s25g5d4:另外就是你提供的例子其實有更好的寫法 像這種形況
s25g5d4:可以改用obj.style[css]=value
s25g5d4:唯background-color這種命名方式要改成駱駝命名法
s25g5d4:http://jsfiddle.net/fYVMx/2/
emn178:closure是javascript很重要的特性,也是正確的做法15F 01/19 21:01

--
※ 看板: dinos 文章推薦值: 0 目前人氣: 0 累積人氣: 130 
作者 StarTouching 的最新發文:
點此顯示更多發文記錄
分享網址: 複製 已複製
guest
x)推文 e)編輯 d)刪除 ^x)轉錄 同主題: =)首篇 [)上篇 ])下篇