前端之JS(五)

來源:互聯網
上載者:User

標籤:域控   ges   語言   執行   賦值   自己   tle   try   生命週期   

js的範圍

範圍是JavaScript最重要的概念之一,想要學好JavaScript就需要理解JavaScript範圍和範圍鏈的工作原理。

任何程式設計語言都有範圍的概念,簡單的說,範圍就是變數與函數的可存取範圍,即範圍控制著變數與函數的可見度和生命週期。在JavaScript中,變數的範圍有全域範圍和局部範圍兩種。

範圍

1. 全域範圍(Global Scope)

在代碼中任何地方都能訪問到的對象擁有全域範圍,一般來說一下幾種情形擁有全域範圍:

(1)最外層函數和在最外層函數外面定義的變數擁有全域範圍

var name="yuan";    function foo(){        var age=23;        function inner(){            console.log(age);        }        inner();    }    console.log(name);    // yuan    //console.log(age);   // Uncaught ReferenceError: age is not defined    foo();                // 23    inner();              // Uncaught ReferenceError: inner is not defined

(2)所有末定義直接賦值的變數自動聲明為擁有全域範圍,例如:

    var name="yuan";    function foo(){        age=23;        var sex="male"    }    foo();    console.log(age);   //  23    console.log(sex);   // sex is not defined

變數blog擁有全域範圍,而sex在函數外部無法訪問到。

(3)所有window對象的屬性擁有全域範圍

一般情況下,window對象的內建屬性都都擁有全域範圍,例如window.alert()、window.location、window.top等等。

2. 局部範圍(Local Scope)

和全域範圍相反,局部範圍一般只在固定的程式碼片段內可訪問到,最常見的例如函數內部,所有在一些地方也會看到有人把這種範圍成為函數範圍.

如樣本1中的age與inner都只有局部範圍。(js中if、for沒有自己的範圍)

範圍鏈(Scope Chain)

在JavaScript中,函數也是對象,實際上,JavaScript裡一切都是對象。函數對象和其它對象一樣,擁有可以通過代碼訪問的屬性和一系列僅供JavaScript引擎訪問的內部屬性。其中一個內部屬性是[[Scope]],由ECMA-262標準第三版定義,該內部屬性包含了函數被建立的範圍中對象的集合,這個集合被稱為函數的範圍鏈,它決定了哪些資料能被函數訪問。

樣本示範

please have a try:

//-----**********************例1*********************************var s=12;    function f(){        console.log(s);         var s=12;          // if s=12        console.log(s)    }    f();//-----**********************例2*********************************var s=10;function foo(){  console.log(s);  var s=5;  console.log(s);  function s(){console.log("ok")}// 函數的定於或聲明是在詞法分析時完成的,執行時已不再有任何操作  console.log(s);}foo();//-----***********************例3********************************function bar(age) {        console.log(age);        var age = 99;
var sex= ‘male‘; console.log(age); function age() {
alert(123) }; console.log(age);
return 100;}result=bar(5);//-----********************************************************
結果分析

我相信大家一定會有想不到的結果,接下來我們就以最複雜的例3來分析整個過程。

當一個函數建立後,它的範圍鏈會被建立此函數的範圍中可訪問的資料對象填充。在函數bar建立時,它的範圍鏈中會填入一個全域對象,該全域對象包含了所有全域變數,如所示:

解析到函數調用時,即bar(5),會產生一個active object的對象,該對象包含了函數的所有局部變數、具名引數、參數集合以及this,然後此對象會被推入範圍鏈的前端,當運行期上下文被銷毀,使用中的物件也隨之銷毀。新的範圍鏈如所示:

過程解析:

function bar(age) {        console.log(age);        var age = 99;        var sex="male";        console.log(age);        function age(){            alert(123);        } ;        console.log(age);        return 100;}result=bar(5);一 詞法分析過程(涉及參數,局部變數聲明,函式宣告運算式):    1-1 、分析參數,有一個參數,形成一個 AO.age=undefine;    1-2 、接收參數 AO.age=5;    1-3 、分析變數聲明,有一個 var age, 發現 AO 上面有一個 AO.age ,則不做任何處理    1-4 、分析變數聲明,有一個 var sex,形成一個 AO.sex=undefine;    1-5 、分析函式宣告,有一個 function age(){} 聲明, 則把原有的 age 覆蓋成 AO.age=function(){};二 執行過程:    2-1 、執行第一個 console.log(age) 時,當前的 AO.age 是一個函數,所以輸出的一個函數    2-2 、這句 var age=99; 是對不 AO.age 的屬性賦值, AO.age=99 ,所以在第二個輸出的age是 99;    2-3 、同理第三個輸出的是 99, 因為中間沒有改變 age 值的語句了。          注意:執行階段:                        function age(){                            alert(123)                        } ;            不進行任何操作,將執行語句複製給age這部操作是在詞法分析時,即運行前完成的。

前端之JS(五)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.