典型例題如下:
<script>
alert(a) // function
a() //10
var a=3;
function a() {
alert(10)
}
alert(a) //3
a=6;
a() // 沒有a這個函式了啊
</script>
複製程式碼
為什麼會有這樣的結果呢?請看下面的例題
例題一
<script>
/*1
alert(a); //underfined(未定義)
var a=1;
*/
/*2
alert(a)
a=1; //報錯,a is not defined
*/
/*
js解析器
1.“找一些東西”(js預解析)var function 引數
根據var找到; a=未定義,所有的變數在正式執行前都提前都賦值了未定義
fn1=function fn1() {alert(2)}
所有的函式,在正式執行程式碼之前,都是整個函式快
2.逐行解讀程式碼
表示式:= + - * 、/ % ++ --! 引數 .......
alert(a)
var a=1;
function fn1() {alert(2)}
*/
</script>
複製程式碼
例題二
<script>
/*
js預解析只會留下一個,!!!變數和函式重名了,只留下函式
第一步:
a=未定義
a=function a() {alert(2)},那麼上面的那個就被幹掉了;
最後,在預解析倉庫裡面只有:
a=function a() {alert(4)}
*/
//開始逐行解讀
alert(a);//function a() {alert(4)}
var a=1;//表示式:a就被改成1了;
alert(a)//1
function a() {alert(2)}//是函式宣告,不是表示式,不會改變a的值
alert(a);//1
var a=3;
alert(a);//3
function a() {alert(4)};
alert(a);//3
a()//報錯,讀完程式碼之後,js倉庫裡面只有a=3;
</script>
複製程式碼
例題三
<!--<script>-->
<!--//1.預解析-->
<!--//2.執行-->
<!--</script>-->
<!--<script>-->
<!--//3.預解析-->
<!--//4.執行-->
<!--</script>-->
<!--
1.
<script>
var a=3;
</script>
<script>
alert(a);//3
</script>
-->
<!--
2. <script>
alert(a);//報錯;a is not defined
</script>
<script>
var a=3;
</script>
-->
複製程式碼
例題四
<script>
var a=1;
function fn1() {
alert(a);//undefined
var a=2;
}
fn1();
alert(a);//1
/*
1.預解析
全域性的 a=未定義
fn1=function fn1() {alert(a);var a=2;}
2.逐行解讀程式碼:
表示式 a=1;
函式呼叫
1)預解析
區域性的 a =未定義
2)逐行解讀程式碼
alert(a)=>未定義
a=2;
*/
</script>
複製程式碼
例題4-1
<script>
var a=1;
function fn1() {
alert(a);//1
a=2;
}
fn1();
alert(a);//2
/*
1.預解析
全域性的 a=未定義
fn1=function fn1() {alert(a); a=2;}
2.逐行解讀程式碼:
表示式 a=1;
函式呼叫
1)預解析
順著這一層的作用域跳到上一層去找(作用域鏈)
2)逐行解讀程式碼
alert(a)//當前作用域沒有,順著這一層的作用域跳到上一層去找(作用域鏈)
a=2也是
先彈出1,再彈出2
*/
</script>
複製程式碼
例題4-2
<script>
var a=1;
function fn1(a) {//引數相當於是一個區域性變數 相當於括號裡面是var a;
alert(a);//undefined
a=2;
}
fn1();
alert(a);//1
/*
1.預解析
a=未定義
fn1=function fn1(a) {alert(a); a=2;}
2.逐行解讀程式碼:
表示式 a=1;
函式呼叫
1)預解析
裡面的a=未定義
2)逐行解讀程式碼
裡面的a=2;
*/
</script>
複製程式碼
例題4-3
<script>
var a=1;//標誌1
function fn1(a) {//引數相當於是一個區域性變數 相當於括號裡面是var a;
alert(a);//1,這個a和標誌1處的a是不相同的,這個a是區域性的,外面的a是全域性的
a=2;
alert(a)//2
}
fn1(a);//這個a是全域性
alert(a);//1
/*
1.預解析
a=未定義
fn1=function fn1(a) {alert(a); a=2;}
2.逐行解讀程式碼:
表示式 a=1;
函式呼叫
1)預解析
裡面的a=未定義
2)逐行解讀程式碼
讀到fn1(a)的時候 就function fn1(var a=1)
找到區域性的a=2
*/
</script>
複製程式碼
例題4-4
<script>
var a=1;
function fn1(a) { //相當於var a;a=1(外面的)
alert(a);//1
var a=2;
console.log(a);//2
}
fn1(a);
alert(a);//1
</script>
複製程式碼
例題4-5
<script>
var a=1;
function fn1(a) {
arguments[0]=3;
alert(a);//3
var a=2;
console.log(a);//2
}
fn1(a);
alert(a);//1
</script>
複製程式碼
例題5 想要獲取函式內的值
<script>
//想要獲取函式內的值
// 一
/*
var str=''
function fn1() {
var a='1';
str=a;
}
fn1();
alert(str)
*/
// 二
function fn2() {
var a='100元';
fn3(a);
}
fn2()
function fn3(b) {
alert(b)
}
</script>
複製程式碼
例題6
<script>
/*
函式的大括號才是一個域
if條件判斷的大括號不是一個作用域,var 寫在大括號裡面和外面是一樣的
if(1){
var a=1;
}
alert(a);
for 迴圈的{}也不是一個塊級作用域
是作用域的標誌是先解析後執行
*/
/*
alert(a);//undefined
if(true){
var a=1;
}*/
/*
alert( fn1 );//underfine(最新的瀏覽器),ie10及以下是可以彈出函式的。。。
if(true){
var a=1;
function fn1() {
alert(123)
}
}*/
/*
//所以,以上程式碼要寫成
alert( fn1 );
var a=1;
function fn1() {
alert(123)
}
if(true){
}*/
</script>
複製程式碼
例題7
<body>
<input type="button" value="1">
<input type="button" value="2">
<input type="button" value="3">
<script>
/*
//1.
window.onload=function () {
var oBtn=document.getElementsByTagName('input');
for(var i=0;i<oBtn.length;i++){
oBtn[i].onclick=function () {
console.log(i);//3
}
}
}*/
/* //2
window.onload=function () {
var oBtn=document.getElementsByTagName('input');
for(var i=0;i<oBtn.length;i++){
oBtn[i].onclick=function () {
console.log(i);//undefined 因為函式域解析了,來自下面for的var i;
for(var i=0;i<oBtn.length;i++){
oBtn[i].style.background='yellow'
}
}
}
} */
</script>
</body>
複製程式碼