變量:
1、基本類型
指簡單的數(shù)據(jù)段,源自以下5種:
基本類型值在內(nèi)存中占據(jù)固定大小的空間,因此被保存在棧內(nèi)存中
- Undefined
- Null
- Boolean
- Number
- String
提示:不允許給基本類型添加屬性(盡管這樣做不會(huì)導(dǎo)致任何錯(cuò)誤):
var name = ‘Bert’;
name.age = 27;
alert(name.age); //undefined
<span>
</span>
說明:只能給引用類型值動(dòng)態(tài)地添加屬性,以便將來使用。
var num1 = 5; var num2 = num1;
num1中保存的值是5。當(dāng)使用num1的值來初始化num2是,num2中也保存了值5.但num2中的5與num1中的5是完全獨(dú)立的,該值知識(shí)num1中5的一個(gè)副本。
基本類型的賦值是拷貝一份副本給另一個(gè)變量,兩個(gè)變量參與任何操作不會(huì)相互影響。
2、引用類型
指那些可能由多個(gè)值構(gòu)成的對(duì)象
注意:引用類型的值是保存在內(nèi)存中的對(duì)象。與其他語言不同,JavaScript不允許直接訪問內(nèi)存中的位置,也就是說不能直接操作對(duì)象的內(nèi)存空間。在操作對(duì)象時(shí),實(shí)際上是在操作對(duì)象的引用(內(nèi)存地址)而不是實(shí)際的對(duì)象。為此,引用類型的值是按引用訪問的。
引用類型的賦值:
引用變量間的復(fù)制操作,也是將存儲(chǔ)在變量對(duì)象中的值復(fù)制一份放到新變量中,不同的是這類值是指針(內(nèi)存中的一段地址),這個(gè)指針指向存儲(chǔ)在推中的一個(gè)對(duì)象。
復(fù)制操作結(jié)束后,兩個(gè)變量實(shí)際上將引用同一個(gè)對(duì)象。因此,改變其中一個(gè)變量,就會(huì)影響另一個(gè)變量。
var obj1 = new Object();
var obk2 = obj1;
obj1.name = "Bert";
alert(obj2.name); // bert
3、參數(shù)傳遞
ECMAScript中所有的函數(shù)的參數(shù)都是按值傳遞的。也就是說,把函數(shù)外部的值復(fù)制給函數(shù)內(nèi)部的參數(shù),就和把值從一個(gè)變量復(fù)制到另一個(gè)變量一樣。
在向參數(shù)傳遞基本類型的值時(shí),被傳遞的值會(huì)被復(fù)制給一個(gè)局部變量(即命名參數(shù),或者用ECMAScript的概念來說,就是arguments對(duì)象中的一個(gè)元素)。
4、類型檢測
typeof
typeof
操作符是確定一個(gè)變量是字符串、數(shù)值、布爾值、還是undefined的最佳工具。
如果變量的值是一個(gè)對(duì)象或null,則typeof操作符會(huì)像下面例子中所示的那樣返回 object
var a = "Bert";
var b = true;
var c = 22;
var d;
var e = null;
var f = new Object();
alert(typeof a); // string
alert(typeof b); // boolean
alert(typeof c); // number
alert(typeof d); // undefined
alert(typeof e); // object
alert(typeof f); // object
instanceof
檢測引用類型使用 instanceof
操作符
如果變量是引用類型(根據(jù)它的原型鏈來識(shí)別)
instanceof
返回 true 或 false
alert(person instanceof Object); // 變量 person 是 Object 類型嗎?
alert(colors instanceof Array); // 變量 colors 是 Array 類型嗎?
alert(pattern instanceof RegExp); // 變量 pattern 是 RegExp 類型嗎?
注意,匹配的對(duì)象首字母大寫
5、執(zhí)行環(huán)境及作用域
執(zhí)行環(huán)境是JavaScript中最為重要的一個(gè)概念。(執(zhí)行環(huán)境有全局執(zhí)行環(huán)境和函數(shù)執(zhí)行環(huán)境之分)
執(zhí)行環(huán)境定義了變量或函數(shù)有權(quán)訪問的其他數(shù)據(jù),決定他們各自的行為。
每個(gè)執(zhí)行環(huán)境都有一個(gè)與之關(guān)聯(lián)的 變量對(duì)象
,環(huán)境中定義的所有變量和函數(shù)都保存在這個(gè)對(duì)象中。
雖然我們編寫的代碼無法訪問這個(gè)對(duì)象,單解析器在處理數(shù)據(jù)時(shí)會(huì)在后臺(tái)使用它。
在 Web 瀏覽器中,全局執(zhí)行環(huán)境被認(rèn)為是window對(duì)象(全局執(zhí)行環(huán)境值到應(yīng)用程序退出,例如關(guān)閉網(wǎng)頁或?yàn)g覽器時(shí)才會(huì)被銷毀)
函數(shù)(執(zhí)行環(huán)境)
每個(gè)函數(shù)第一頁租戶的 執(zhí)行環(huán)境
。 當(dāng)執(zhí)行流進(jìn)入一個(gè)函數(shù)時(shí)(執(zhí)行一個(gè)函數(shù)),函數(shù)的環(huán)境就會(huì)被推入一個(gè)環(huán)境棧中。
在函數(shù)執(zhí)行之后,棧將其環(huán)境彈出,把控制權(quán)返回給之前的執(zhí)行環(huán)境。(假設(shè)之前的執(zhí)行環(huán)境仍是一個(gè)函數(shù),那么就會(huì)循環(huán)釋放直至根環(huán)境)
作用域鏈
當(dāng)代碼在一個(gè)執(zhí)行環(huán)境中執(zhí)行時(shí),會(huì)創(chuàng)建變量對(duì)象的一個(gè) 作用域鏈
。作用域鏈的用途是保證對(duì)執(zhí)行環(huán)境有權(quán)訪問的所有變量和函數(shù)的有序訪問。
那 this 和
作用域鏈
的關(guān)系如何解釋?
作用域鏈的前端始終都是單簽執(zhí)行的代碼所在環(huán)境的變量對(duì)象。
如果這個(gè)環(huán)境是函數(shù),則將其 活動(dòng)對(duì)象
作為變量對(duì)象。活動(dòng)對(duì)象在最開始時(shí)只包含一個(gè)變量,即 arguments 對(duì)象(這個(gè)對(duì)象在全局環(huán)境中是不存在的)。
簡單來說作用域鏈?zhǔn)且粚右粚訌母恋椎臉湫谓Y(jié)構(gòu),底層可以訪問頂層的數(shù)據(jù),而頂層無法訪問底層的數(shù)據(jù)(勞資我出生的時(shí)候怎么會(huì)知道自己將來會(huì)生幾個(gè)兒子??! 放過來說做兒子的肯定知道自己的勞資是誰)
延長作用域鏈
- try - catch 語句的 catch 塊
- with語句
這兩個(gè)語句都會(huì)在作用域鏈的前端添加一個(gè)變量對(duì)象。
with:會(huì)將制定的對(duì)象添加到作用域鏈中。
catch:會(huì)創(chuàng)建一個(gè)新的變量對(duì)象,其中包含的是被拋出的錯(cuò)誤對(duì)象聲明。
沒有塊級(jí)作用域
JavaScript 沒有塊級(jí)作用。
- 在if、for語句中聲明的變量會(huì)被保存在當(dāng)前執(zhí)行環(huán)境中,在其執(zhí)行結(jié)束時(shí)不會(huì)被銷毀。
- 不使用 var 聲明的變量默認(rèn)綁定到全局環(huán)境中。
6、垃圾回收、性能問題
在有的瀏覽器中可以出發(fā)垃圾收集過程(不建議使用)
- 用 window.CollectGarbage()方法會(huì)立即執(zhí)行垃圾收集。
- 在Opera7及更高版本中,調(diào)用 window.opera.collect()也會(huì)啟動(dòng)垃圾收集例程。
有那么一點(diǎn)意思..
有垃圾回收機(jī)制的語言編寫程序一般不必操心內(nèi)存管理問題。
出于安全考慮,Web瀏覽器可用內(nèi)存數(shù)量通常要少于桌面應(yīng)用。因此,確保占用最少的內(nèi)容可以讓頁面獲得更好的性能。
優(yōu)化內(nèi)存占用的最佳方式,就是為執(zhí)行中的代碼只保存必要的數(shù)據(jù)。一旦數(shù)據(jù)不再有用,最好通過將其值設(shè)置為null來釋放其引用 ---- 這個(gè)做法叫做 解除引用
。