- 數據類型包括基本數據類型與復雜的數據類型object類型,而object類型在這里也說了,可以被稱為引用類型。
在js內,我們是通過關鍵字var
來聲明變量的。任何類型的變量均用var來聲明。 - 針對不同的數據類型,變量值的類型也會不同,同樣也可以分為基本類型值與引用類型值兩種。
- 變量被聲明為基本類型,則其值也是基本類型值,基本類型值是實際值,js允許直接操作保存在變量中的值。
- 變量被聲明為引用類型,則其值也是引用類型值,引用類型值是保存內存中的對象,js不允許直接操作他,則當操作該變量時,是在操作該對象的引用。(這個機理需要明白,才能理解其復制的機制)
- 關于聲明變量時,內存的分配
- 基本類型值:按值訪問,操作的是他們實際保存在棧中的值;
引用類型值:按引用訪問,當查詢時,我們需要先從棧中讀取內存地址,然后再順藤摸瓜地找到保存在堆內存中的值; - 變量的初始化
-
基本類型值
var num1=5;
棧內存 -
引用類型值
var obj1=new object();
對象內存圖
-
-
檢測類型
- typeof
var s="dudu";
alert(typeof s);// string
typeof操作符是確定變量為基本類型的。但是對于變量的值為對象或null時,那么typeof會返回“object”。 - instanceof
alert(person instanceof Array);//變量person是Array類型么?
因為所有引用類型都是Object的實例,所以
alert(person instanceof Object);//返回true
- typeof
-
執行環境及作用域
- 執行環境定義了變量或函數有權訪問的其他數據,每個執行環境都有一個與之關聯的變量對象,該執行環境中,定義的所有變量和函數都保存在這個對象中。
- 在web瀏覽器中,全局執行環境中,所有變量都保存在window對象中。
- 每個函數都有自己的執行環境,當執行流進入一個函數時,函數的環境就會被推入一個環境棧中,而在函數執行之后,棧將其環境彈出。
- 作用域鏈——當代碼在一個環境中執行時,會創建變量對象的一個作用域鏈。其作用就是保證對執行環境有權訪問的所有變量和函數的有序訪問。作用域鏈的最前端,始終都是當前執行的代碼所在環境的變量對象,而作用域鏈的最后端,則是全局執行環境的變量對象。
- 如果環境是函數,則將其活動對象作為變量對象,活動對象,最開始只是包含一個變量即arguments對象。
- 標示符解析——即沿著作用域鏈一級一級的搜索標識符的過程,搜索過程始終從作用鏈的最前端開始,然后逐級向后回溯,直至找到標識符為止。為什么要解析呢?因為在局部環境中使用的非自己環境的變量對象內的變量,則需要看看,這個變量在不在作用域鏈上的外層環境內。
- 規律:內部環境可以通過作用域鏈訪問所有的外部環境,但是外部環境不能訪問內部環境中的任何變量和函數。
- ** 作用域鏈的延長**
因為有些語句可以在作用域鏈的前端臨時增加一個變量對象,該變量對象也會在代碼執行后被移除。- 第一種情況:
try catch
語句的catch塊。會創建一個新的變量對象,其中包含的是被拋出的錯誤對象的聲明。 - 第二種情況:
with
語句。會將指定的對象添加到作用域鏈中,即添加到當前執行環境的變量對象中,也就是當前執行換進的變量對象中的變量也可以訪問with語句指定的對象。
var qs="";
with(location){
var url=href+qs
}
- 第一種情況:
- js沒有塊級作用域
這里的塊級作用域,更多的是強調沒有像其他類C的語言中,由花括號封閉的代碼塊都有自己的作用域。但是函數是js中唯一擁有自身作用域的結構。 - 沒有塊級作用域,那些
if(){}
與for(){}
則需要注意啦。大括號里新建的變量,括號結束后,可不會自動退還內存的。 - 聲明變量
- var聲明的變量會自動添加到最近的環境中,如果某變量在函數內沒有使用var聲明,便直接初始化,那么該變量則自動添加到全局環境中。
-
變量聲明提升——當前作用域內的聲明都會提升到最前面,包括變量和函數的聲明。
function(){
var a="1";
var f=function(){};
var b="2";
}
變量afb的聲明會被提升到函數作用域的最前面類似如下:
function(){
var a,f,b;
a="1";
f=function(){};
b="2";
}
注意函數表達式的聲明并沒有被提升,這也是函數表達式與函數聲明的區別,看下面
function(){
var f1;function f2(){};
f1();//雖然f1的聲明被提升,但是f1提升后的值為undefined。所以此句會報錯。
f2();
var f1=function(){};
}
- 查詢標識符
- 當某個環境中為了讀取或寫入而引用一個標示符時,必須通過搜索來確定該標示符實際代表什么。搜索過程從作用域鏈的前端開始,向上逐級查詢與給定名字匹配的標識符,如果在局部環境中找到,則停止搜索。
- 因此訪問局部變量要比訪問全局變量更快,是吧!
-
標識符同名問題
js中的一個名字以四種方式進入作用域,其優先級如下:
1、語言內置:this、arguments
2、形式參數:
3、函數聲明:
4、變量聲明:
名字聲明的優先級如上,但是初始化確實按照該名字在聲明未提前之前的代碼順序,進行初始化。
function(){
var foo;
alert(typeof foo);//function
function foo(){}
foo="foo";
alert(typeof foo);//string
}
JS—變量、作用域、內存
最后編輯于 :
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
- 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
- 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
- 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
推薦閱讀更多精彩內容
- 目錄 UIDevice設備相關信息設備電量近距離傳感器設備性能、界面模式NSBundle獲取應用名稱應用短版本號應...