我是來自Python和Clojure的javascript/dom noob,引用dom中的東西的語義讓我很困惑。當通過dom元素循環時,何時使用「this」以及何時使用循環變量?
採取從一些代碼,我只是寫成瀏覽器擴展程序,以識別匹配testdownloadpage
定義的標準頁面的子集,然後掛在PDF下載鏈接事件監聽器攔截並颳去他們:
function hanglisteners() {
if (testdownloadpage(url)) {
var links = document.getElementsByTagName("a");
for (i = 0, len = links.length; i < len; i++) {
var l = links[i];
if (testpdf(l.href)) {
l.addEventListener("click", function(e) {
e.preventDefault();
e.stopPropagation();
e.stopImmediatePropagation();
getlink(this.href);
}, false);
};
};
};
};
以下摘錄
最初,我打電話getlink
底部閱讀getlink(l.href)
,我想(顯然天真)該代碼會發生什麼,它會循環通過每個匹配的鏈接,並打擊每個調用getlink的監聽器在該鏈接的網址上。但那根本不起作用。我試圖用this.href
代替l.href
,並開始工作。
我不確定爲什麼this.href
工作時l.href
沒有。我最好的猜測是,JavaScript解釋器不會在addEventListener
調用中評估l.href
,直到某個點後,l
已更改爲其他(??)。但我不知道爲什麼應該是這樣,或者如何知道javascript何時評估函數調用的參數,以及何時不會...
現在我擔心上層調用testpdf(l.href)
。該功能旨在檢查以確保鏈接是一個PDF下載鏈接,然後再將監聽器懸掛在該鏈接上。但是,是否要在循環內評估l.href
,並因此正確評估每個鏈接?或者是在循環之後的某個時刻也要評估,我應該使用this.href
來替代嗎?
請問一些靈魂可以向我解釋底層的語義,這樣我就不必猜測引用循環變量還是提到this
是正確的?謝謝!
編輯/添加:
的共識似乎是,我的問題是(顯然知名的)問題,即在環內功能的範圍內泄漏S.T.受害者當它們被調用時,除非內部函數關閉它所使用的變量,否則它們最終綁定到循環的最後一個元素。但是:爲什麼這個代碼然後工作?
var links = document.getElementsByTagName("a");
for (i = 0, len = links.length; i < len; i++) {
let a = links[i];
a.addEventListener("click", function(e) {
e.preventDefault();
e.stopPropagation();
e.stopImmediatePropagation();
console.log(a.href);
});
};
<html>
<head>
<title>silly test</title>
</head>
<body>
<p>
<a href="link1">Link 1</a>
<a href="link2">link2</a>
<a href="link3">link 3</a>
</p>
</body>
</html>
基於這些問題的答案,我期望點擊每一個環節登錄「鏈接3」,但它們實際上記錄正確的/預期天真結果...
看起來像一個重複的http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example – elclanrs
當一個函數被用作事件處理程序,它的'this'被設置到事件觸發的元素(某些瀏覽器不遵循此慣例,用於使用除addEventListener之外的其他方法動態添加的偵聽器)。 –
嗯@elclanrs你是說這個問題與循環沒有任何關係,但是有一些與範圍泄漏到內部函數? –