1)基本類型指的是簡(jiǎn)單的數(shù)據(jù)段,而引用類型指的是由多個(gè)值構(gòu)成的對(duì)象
基本數(shù)據(jù)類型有:undefined,null,boolean,number和string這五種數(shù)據(jù)類型是按值訪問的姓迅,可以保存在變量的實(shí)際值中
引用類型的值保存在內(nèi)存中
2)動(dòng)態(tài)屬性
引用類型:可以添加屬性和方法也可以改變和刪除方法。
例如:var person = new Object(); person.name = 'chenshuwen';
console.log(person.name) //chenshuwen
* 但是不能給基本類型添加屬性,添加也不會(huì)導(dǎo)致錯(cuò)誤*
var name = 'chenshuwen' name.age = 27;console.log(name.age) //undefined ;
3)賦值變量证鸥、
如果一個(gè)變量像一個(gè)變量復(fù)制基本數(shù)據(jù)類型措译,會(huì)在變量上 創(chuàng)建一個(gè)新值,然后把值分配到 新的
位置上,例子:var num=5偎行;var num2=num1 ;num1和num2中保存的5是完全獨(dú)立的川背,任何操作不
會(huì)相互影響。
然而如果復(fù)制引用類型這個(gè)值的副本是一個(gè)指針蛤袒,指向存儲(chǔ)在堆中的一個(gè)對(duì)象熄云,這樣就會(huì)相互干
擾。
4.1.2 傳遞參數(shù)
訪問變量有按值和按引用兩種方式妙真,而所有函數(shù)的參數(shù)都是按值傳遞
function addTen(num){
num += 10;
return num
}
var count = 20;
var result = addTen(count);
count ==> 20 // 沒有變化
result ==> 30
使用對(duì)象傳參
function setName(obj){
obj.name = 'www'
}
var person = new Object();
setName(person);
person.name ==> 'www'
在這個(gè)函數(shù)內(nèi)部缴允,obj和person引用的是用一個(gè)對(duì)象
function setName(obj){
obj.name = 'wwww';
obj = {};
obj.name = 'greg';
}
var person = {};
setName(person);
person.name ==> 'www'
即使在函數(shù)內(nèi)部修改了參數(shù)的值,但原始的引用仍然保持不變珍德。當(dāng)在函數(shù)內(nèi)部重寫了obj時(shí)练般,
這個(gè)變量引用的就是一個(gè)局部對(duì)象了,這個(gè)局部對(duì)象
會(huì)在函數(shù)執(zhí)行完畢后立即被銷毀锈候;
所有的這些都說明踢俄,函數(shù)參數(shù)是按值傳遞的,函數(shù)的參數(shù)一定程度上說是局部變量晴及;
4.1.3 檢測(cè)類型
檢測(cè)字符串都办,數(shù)值,布爾虑稼,undefined琳钉,用typeof
typeof檢測(cè)引用類型值都返回Object
typeof null ==> 'object';
使用typeof 檢測(cè)undefined會(huì)出現(xiàn)一個(gè)問題:
var name;
var sex = undefined;
typeof name ==> undefined //檢測(cè)定義了未賦值變量name為undefined
typeof age ==> //檢測(cè)未定義變量age ,返回undefined
typeof sex ==> //檢測(cè)值為undefined的變量sex蛛倦,返回undefined
這個(gè)可能會(huì)造成一些混亂歌懒,所以確保只有未定義時(shí),才返回undefined溯壶。其他兩種情況及皂,請(qǐng)盡量避免。
檢測(cè)引用類型:instanceof
var arr = [];
arr instanceof Array ==> true
使用instanceof檢測(cè)基本類型且改,則始終會(huì)返回false验烧,因?yàn)榛绢愋筒皇菍?duì)象
4.2 執(zhí)行環(huán)境和作用域
執(zhí)行環(huán)境:定義了變量或函數(shù)有權(quán)訪問的其他數(shù)據(jù),決定了他們各自的行為又跛;
局部環(huán)境在執(zhí)行完畢后碍拆,其中的變量和函數(shù)定義也會(huì)被銷毀
全局環(huán)境在應(yīng)用程序退出,關(guān)閉網(wǎng)頁或退出瀏覽器時(shí),其中的變量和函數(shù)定義會(huì)被銷毀
每個(gè)函數(shù)都有自己的執(zhí)行環(huán)境感混。當(dāng)執(zhí)行流進(jìn)入到一個(gè)函數(shù)中時(shí)端幼,
函數(shù)的環(huán)境會(huì)被推入一個(gè)環(huán)境棧中,而在函數(shù)執(zhí)行之后弧满,棧將其環(huán)境彈出婆跑,把控制權(quán)還給之前的執(zhí)行環(huán)境。
每個(gè)環(huán)境都可以向上搜索作用域鏈庭呜,以查詢變量和函數(shù)名洽蛀,但任何環(huán)境都不能通過向下搜索作用域鏈而進(jìn)入另一個(gè)執(zhí)行環(huán)境
4.2.1 延長(zhǎng)作用域鏈
try-catch
with語句
4.2.2 沒有塊級(jí)作用域
if(true) {
var color = 'blue'
}
alert(color) ==> 'blue'
由于不存在塊級(jí)作用域,所以if語句的變量聲明會(huì)將變量添加到當(dāng)前的執(zhí)行環(huán)境(這里是全局環(huán)境)
for (var i = 0; i < 10; i ++) {
doSomething(i)
}
alert(i) ==> 10
由于不存在塊級(jí)作用域疟赊,由for語句創(chuàng)建的變量i即使在for循環(huán)執(zhí)行結(jié)束后,
也依舊會(huì)存在于循環(huán)外部的執(zhí)行環(huán)境中
- 聲明變量
使用var聲明的變量會(huì)自動(dòng)被添加到最接近的環(huán)境中峡碉,在函數(shù)內(nèi)部近哟,
最接近的環(huán)境就是函數(shù)的局部環(huán)境,未經(jīng)var聲明過的變量鲫寄,會(huì)被自動(dòng)添加到全局環(huán)境中吉执,
4.3 垃圾收集
javascript具有自動(dòng)垃圾收集機(jī)制,執(zhí)行環(huán)境會(huì)負(fù)責(zé)管理代碼執(zhí)行過程中使用的內(nèi)存地来,所需內(nèi)存的分配以及無用內(nèi)存的回收完全實(shí)現(xiàn)了自動(dòng)管理戳玫。
這種垃圾收集機(jī)制原理:找出那些不再繼續(xù)使用的變量,然后釋放其占用的內(nèi)存未斑;
怎么樣找到哪些變量將不再被繼續(xù)使用咕宿?
垃圾收集器必須跟蹤哪個(gè)變量有用哪個(gè)沒有用,對(duì)于不再有用的變量打上標(biāo)記蜡秽,以備將來收回其占用的內(nèi)存府阀;
用于標(biāo)示無用變量的兩個(gè)策略:
4.3.1 標(biāo)記清除:
在變量進(jìn)入環(huán)境和離開環(huán)境時(shí),分別為其添加標(biāo)記芽突,清除離開的變量试浙,釋放內(nèi)存;
4.3.2 引用計(jì)數(shù)(不太常用)
4.3.3 性能問題
4.3.4 管理內(nèi)存
js在進(jìn)行內(nèi)存管理和垃圾收集時(shí)面臨一個(gè)問題寞蚌,js分配給web瀏覽器的可用內(nèi)存數(shù)量通常要比分配給桌面應(yīng)用的少田巴,這樣做是出于安全考慮,防止運(yùn)行js的網(wǎng)頁耗盡全部系統(tǒng)系統(tǒng)內(nèi)存而導(dǎo)致系統(tǒng)崩潰挟秤,因此壹哺,確保占用最少內(nèi)存可以讓頁面獲得更好的性能;
優(yōu)化內(nèi)存最佳方式艘刚,就是為執(zhí)行中的代碼只保存必要的數(shù)據(jù)斗躏,一旦數(shù)據(jù)不再有用,
最好通過將其設(shè)置為null來釋放其引用,這個(gè)方法叫做解除引用啄糙,這一做法
適用于大多數(shù)全局變量和全局對(duì)象的引用笛臣,因?yàn)榫植孔兞繒?huì)在它們離開執(zhí)行環(huán)境時(shí)自動(dòng)被解除引用;
如下例:
function createPerson(name){
var localPerson = new Object();
localPerson.name = name;
return localPerson;
}
var globalPerson = createPerson('wang');
//手工解除globalPerson的引用
globalPerson = null;