都是Javascript的作用域惹得禍
案件重現
今天有位然之OA係統的定製開發用戶谘詢了個問題,他想在新加的功能模塊的操作麵板中,實現用戶點擊刪除按鈕時提示友好提醒,如下:
問題很簡單,雖然他自己最終達到目的效果了,但不知道起初問題出在哪裏。通過交流了解,他開始是這麼做的,大致問題代碼如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <script> window.onload=function () { function confirmdelete() { return window.confirm("你確定要刪除嗎?"); } } </script> </head> <body> </body> <?php echo "<a onclick='confirmdelete()'>刪除</a>"; ?>
結果未能達到目的,點擊刪除按鈕沒有效果,然後這位朋友將window.onload刪除後,再試了一下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <script> function confirmdelete() { return window.confirm("你確定要刪除嗎?"); } </script> </head> <body> </body> <?php echo "<a onclick='return confirmdelete()'>刪除</a>"; ?>
結果成功了,點擊刪除按鈕成功觸發事件,彈出提示框。於是這位朋友就懷疑是不是window.onload將JS代碼在頁麵全部加載完畢後再執行就無效了,是不是代碼執行順序的問題。
事實真的是這樣麼?
當然不是。相信很多朋友已經發現了真正的問題所在——作用域。
這位朋友起初將confirmdelete函數寫成了onload事件的一個內函數,那麼confirmdelete就是一個閉包,而刪除事件觸發後,它是在全局作用域中查找調用函數,由於全局上是找不到這個函數,所以無效。
所以這裏我們可以將閉包改為全局變量即可,在JS函數中,聲明變量時不用var關鍵字,則它就是全局變量。代碼如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <script> window.onload=function () { confirmdelete = function() { return window.confirm("你確定要刪除嗎?"); } } </script> </head> <body> <?php echo "<a onclick='confirmdelete()'>刪除</a>"; ?> </body>
總結:
有時困擾大牛的不是前麵寬闊難以跨越的激流河道,而是身上甩不掉的蒼蠅蚊蟲。鑽完牛角尖後,回過頭來發現問題原來如此簡單。是否日複一日地寫業務代碼寫的麻木了?是否發現天天刷怪升級,但技能點卻總提不上去?不妨返璞歸真,溫故而知新。最近自己也深有感觸,越來越感受到最可怕的事情莫過於今天過的和昨天沒有不同。所以居安思危,每天都要改變,每天都要有提升進步。

最後更新:2017-08-13 22:50:21