閱讀475 返回首頁    go 阿裏雲 go 技術社區[雲棲]


都是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>


這樣也是同樣有效的。最後隻好建議這位朋友在深入了解下JS的變量作用域和閉包等概念。



總結:

有時困擾大牛的不是前麵寬闊難以跨越的激流河道,而是身上甩不掉的蒼蠅蚊蟲。鑽完牛角尖後,回過頭來發現問題原來如此簡單。是否日複一日地寫業務代碼寫的麻木了?是否發現天天刷怪升級,但技能點卻總提不上去?不妨返璞歸真,溫故而知新。最近自己也深有感觸,越來越感受到最可怕的事情莫過於今天過的和昨天沒有不同。所以居安思危,每天都要改變,每天都要有提升進步。

1PZ2b6Oq5UyKFF.gif

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

  上一篇:go  linux(centos)下安裝PHP的PDO擴展
  下一篇:go  oracle數據庫優化一則