瞭解JavaScript的同學可能知道,JavaScript語言由於設計原因,導致語言本身存在很多先天性的不足,當然這並非設計者有意的,js語言最初是被設計來作為網頁交互的腳本語言,依照現有的js語法來看,其最初的需求已經完全能夠滿足。互聯網的發展極大的提高了對web端的要求,不僅僅要求簡單的頁面交 ...
瞭解JavaScript的同學可能知道,JavaScript語言由於設計原因,導致語言本身存在很多先天性的不足,當然這並非設計者有意的,js語言最初是被設計來作為網頁交互的腳本語言,依照現有的js語法來看,其最初的需求已經完全能夠滿足。互聯網的發展極大的提高了對web端的要求,不僅僅要求簡單的頁面交互,已經趨於app的概念,這才暴漏出JavaScript語言設計上的種種問題。對於開發者來說,理清“坑點”併在實際開發中正確的規避才是重點。
1、任何js代碼都有自己的作用域
ES6之前,使用var聲明變數的時候,很容易被忽略的一點是,var聲明的變數的作用域;
1)在函數中var聲明的變數,其作用域是在函數體內部,即函數外部是訪問不到的:
<script> function foo() { var myname = "foo_name"; console.log(myname);//foo_name } foo(); console.log(myname);//error </script>
這是很容易理解的,因為JavaScript本身有函數作用域。
2)不在函數中var聲明的變數:
<script> var myname_1 = "myname_1"; { var myname_2 = "myname_2"; } console.log(myname_1);//myname_1 console.log(myname_2);//myname_2,不會error </script>
這也很容易理解,因為JavaScript中沒有塊級作用域,在{}中聲明的變數和不使用{}沒有區別。
3)這裡很容易很忽略的一點是,以上js代碼都有作用域,就是全局作用域window,所有聲明的變數都有自己的作用域,只不過常見的是作用域是全局作用域即window,很容易被忽略掉,導致沒有作用域的認知。有時候這點誤區會導致驗證的錯誤。
新建html頁面html1.html,首先看看如何驗證以上的說法,
<script> function showName () { console.log("這裡是showName"); } window.showName();//這裡可以驗證shownName的作用域在window </script>
以上代碼很容易驗證了showName函數的作用域是window。
新建頁面html2.html,並寫入一下js:
<script> function showNameToo () { console.log("這裡是showNameToo"); } window.showNameToo(); </script>
現在在html1頁面中使用iframe引用html2頁面,在html1中添加js代碼:
<script> function showName () { console.log("這裡是showName"); } window.showName(); var iframe = document.querySelector("#iframe"); iframe.src = "html2.html"; window.iframe.contentWindow.showNameToo(); </script>
在html2.html中添加如下代碼:
<script> function showNameToo () { console.log("這裡是showNameToo"); } window.showNameToo(); window.parent.showName(); </script>
在頁面上打html1(通過伺服器打開,不能直接打開文件),可以看到有趣的現象。
總結:之所以講這個例子,是因為不少新加入前端的同學都會有一個誤區,就是js中只有函數作用域(忽略全局作用域,因為使用的很少)。其實這個觀點很重要,在多模塊開發中,一個模塊就相當於一個頁面的windiw作用域。