JavaScript執行環境及做用域鏈實例分析

一、執行環境:html

每一個執行環境都有一個與之關聯的變量對象,環境中定義的全部變量和函數都保存在這個對象中。前端

執行環境包括全局執行環境和函數執行環境。瀏覽器

全局執行環境是最外圍的一個執行環境,在瀏覽器中,全局執行環境被認爲是是window對象,全部全局變量和屬性都是做爲window對象的屬性和方法建立的。函數

函數執行環境是指函數的執行環境,當執行流進入一個函數時,函數的環境會被推入一個環境棧中,在函數執行以後,棧將其環境彈出,將控制權返回到以前的執行環境。學習

二、做用域鏈:google

當代碼在一個環境中執行時,會建立變量對象的一個做用域鏈。url

做用域鏈的用途:保證對執行環境有權訪問的全部變量和函數的有序訪問。code

做用域鏈的前端,始終是當前執行的代碼所在環境的變量對象,若此環境是函數,則將其活動對象做爲變量對象。活動對象最開始時只包含一個變量,即arguments對象(該對象在全局環境中是不存在的),做用域鏈的下一個對象來自包含環境,再下一個變量則來自下一個包含環境,這樣一直延續到全局執行環境。全局執行環境的變量對象始終是做用域鏈的最後一個對象。htm

每一個環境均可以向上搜索做用域鏈,以查詢變量和函數名,終點就是搜索到全局執行環境,可是任何環境不能經過向下搜索做用域鏈而進入另外一個執行環境。內部環境能夠經過做用域鏈訪問全部的外部環境,但外部環境不能訪問內部環境的任何變量和函數。對象

三、延長做用域鏈:

雖然執行環境只有兩種:全局執行環境和函數執行環境,可是能夠有方法延長做用域鏈,由於有些語句能夠在做用域鏈的前端臨時增長一個變量對象,該變量對象會在代碼執行後被移除。

當執行流進入下列語句時,做用域鏈會延長:

(1)try-catch語句的catch塊:catch語句會建立一個新的變量對象,其中包含的是被拋出的錯誤對象的聲明,該變量對象只在catch塊內部有效,在catch塊外部沒法訪問到。

(2)with語句:with語句會將指定的對象添加到做用域鏈中。 eg1:

function setUrl(){
  var parameter="?name=Alice";
  var url = href + parameter;
  return url;
}
var result = setUrl();
alert(result);//報錯:href is no defined

eg2:

function setUrl(){
  var parameter="?name=Alice";
 with(location) {
 var url = href + parameter;
 }
  return url;
}
var result = setUrl();
alert(result);//http://localhost/text.html?name=Alice

前端全棧學習交流圈:866109386 面向1-3經驗年前端開發人員 幫助突破技術瓶頸,提高思惟能力

with語句接收的是location對象,所以其變量對象中包含了location對象的全部屬性和方法,location對象被添加到了做用域鏈的前端。

eg3:

var obj = {href : "http://www.baidu.com"};
var href = "http://www.sina.cn";
function setUrl(){
  var parameter="?name=Alice";
 with(obj) {
 href = "http://www.google.cn";
 var url = href + parameter;
 }
  return url;
}
var result = setUrl();
alert(result);//http://www.google.cn?name=Alice
alert(href);//http://www.sina.cn

with語句中並無更改變量href的值,而是更改了obj對象的 href 屬性。

也就是說,with中首先查找的是相關對象的屬性,若是沒有,才改變變量的值。

eg4:

var obj = {};
var href = "http://www.sina.cn";
function setUrl(){
  var parameter="?name=Alice";
 with(obj) {
 href = "http://www.google.cn";
 var url = href + parameter;
 }
  return url;
}
var result = setUrl();
alert(result);//http://www.google.cn?name=Alice
alert(href);//http://www.google.cn

去掉obj對象的 href 屬性後,才更改變量href的值。

相關文章
相關標籤/搜索