零JS筆記 | 作用域
瀏覽器:
JS解析器,在域內,一定會有兩步
1)找東西: var function 參數
2)逐行解讀代碼 [碰到script,及fn,會解析執行]
什麼是域: script 全局變量、全局函數
alert(a);
var a = 1;
function fn(){ alert(a) }
//1)找東西 找var function 參數
a = undefined //如果var去掉,則js解析器為空,所以a is not defined
fn = function fn(){ alert(a) } (在倉庫內存放)
//2)逐行解讀代碼
alert(a); 倉庫內為未定義
var a = 1 ; (看見表達式:= + - * / % ++ -- 參數;)(把倉庫內的a = undefined 改為 a = 1)
alert(a); //function a() { alert(4)
var a = 1;
alert(a); //1
function a() { alert(2) ;}
alert(a); //1
var a = 3; //
alert(a); //3
function a() { alert(4) }
alert(a); //3
//1)找東西 找var function 參數
//a = undefined
a = function a() { alert(2) } //又找到a,是函數,變量與函數重命,則只留函數
//a = undefined //重命,只留下函數
a = function a() { alert(4) } //遇到函數,前面被覆蓋;(存到倉庫裏只有這一行)
//2)逐行解讀代碼
alert(a); //倉庫裏有 a = function a() { alert(4) }
var a = 1; //出現表達式,a被修改為 a = 1;
function a() { alert(2) ;} //函數聲明,不是表達式,所以不改東西 a = 1
alert(a); //所以1
var a = 3 //出現表達式,a被修改為 a = 3;
alert(a); //所以是a = 3
function a() { alert(4) } ////函數聲明,不是表達式,所以不改東西 a= 3
alert(a) //a = 3 //倉庫裏無函數了,所以若:
a() //相當於 3(),報錯!
//域是分開執行的 先後順序,自上而下
<script> alert(a) </script> // a is not defined
<script> var a = 1 </script>
var a = 1;
function fn(){
alert(a);
var a = 2;
}
fn();
alert(a);
//1)找東西 找var function 參數
a = undefined
fn = function fn() { alert(a);var a = 2; }
//2)逐行解讀代碼
a = 1;
fn(); //1
//1)找東西 找var function 參數
var a = 2 //a = undefined; // a为局部變量 ,與外面的a無關係 所以只在局部倉庫裏;
//2)逐行解讀代碼
a = 2; //局部垃圾回收機制回收
alert(a) //1 全局倉庫裏
var a = 1;
function fn(){
alert(a);
a = 2; //去掉var,相當於改全局倉庫裏的值;
}
fn(); //1
alert(a); //2
var a = 1;
function fn(a){ //加參數
alert(a); //往上找到參數a,到達不了 var a = 1; 所以預解析a = undefined
a = 2; //局域的a被改為a = 2,執行完後銷毀
}
fn(); //局部a = undefined
alert(a); //全局a = 1
var a = 1;
function fn(a){
alert(a);
a = 2;
}
fn(a);//執行時傳參進來 所以1
alert(a); //1
//獲取fn內的值方法一:
var str = '' //1、定義
function fn(){
var a = 'pig'
str = a //2、str 拿到
}
fn(); ///////////////////////////////////////// 3、一定要執行;
alert(str) //4、可找到pig
//获取fn内的值方法二:
function fn2(){
var a = 'MM';
fn3(a);
}
fn2()
function fn3(e){ //调用参数接收
alert(e); //e = a = 'MM'
}
写代码注意事项:
1、if条件判断非作用域;如下代码,但ff不能对下面的函数进行预解析;兼容性问题,所以若需定义全局变量或全局函数,不要在if或for循环里定义!
//不要這麼寫:
alert(a); //undefined正常
alert(fn) //if非作用域,理论上应该弹出整个fn内容chrome,但在ff上:fn is not defined
if(true){
var a = 1
function fn(){
alert(123)
}
}
//需這麼寫,變量與函數定義在if或for 外面
alert(a); //undefined正常
alert(fn) // function fn(){alert(123)}
var a = 1
function fn(){
alert(123)
}
if(true){
}
var btn = document.getElementsByTagName('input')
for (var i = 0; i < btn.length; i++) { //一個循環
btn[i].onclick = function () {
for (var i = 0; i < btn.length; i++) { //點擊每一個時,循環三次,正常
btn[i].style.background = 'red'
}
}
}
for (var i = 0; i < btn.length; i++) { //一個循環3
btn[i].onclick = function () {
alert(i) //i = 3,執行完for後才點擊,i向上找,所以是3;
}
}
for (var i = 0; i < btn.length; i++) { //一個循環3
btn[i].onclick = function () { //這一塊是作用域,下面有var = 0,所以最開始 彈 i = undefined
alert(i) // undefined
for (var i = 0; i < btn.length; i++) { //如去掉var,則上面的i 必須往上找
btn[i].style.background = 'red'
}
}
}