(注1:如果有問(wèn)題歡迎留言探討射亏,一起學(xué)習(xí)银锻!轉(zhuǎn)載請(qǐng)注明出處鼎姐,喜歡可以點(diǎn)個(gè)贊哦!)
(注2:更多內(nèi)容請(qǐng)查看我的目錄。)
1. JS的數(shù)據(jù)類型
JS變量的數(shù)據(jù)類型的值有兩種:基本類型值和引用類型值涉瘾」泵基本類型值指簡(jiǎn)單的數(shù)據(jù)段赁还,而引用類型值指那些可能由多個(gè)值構(gòu)成的對(duì)象甚负。
基本類型值有以下五種:Undefined斑举、Null、Boolean、Number和String。引用類型值即保存在內(nèi)存中的對(duì)象。
var num1 = 1;
var str1 = '1';
var obj1 = {a: 1};
2. JS的變量復(fù)制
JS對(duì)基本類型的復(fù)制和引用類型的復(fù)制并不相同椒拗「郑基本類型值的復(fù)制實(shí)際上將變量和其存儲(chǔ)的內(nèi)容重新復(fù)制了一份,而引用類型的復(fù)制只是將其保存的指針復(fù)制了一份彪标,實(shí)際存儲(chǔ)對(duì)象的堆并沒(méi)有復(fù)制倍权。
var num1 = 6;
var num2 = num1;
var obj1 = {a: 1};
var obj2 = obj1;
3. JS的參數(shù)傳遞是按值傳參
JS的參數(shù)是按值傳遞,即將函數(shù)外部的值復(fù)制給函數(shù)內(nèi)部的參數(shù),其復(fù)制過(guò)程如前所述薄声。那么對(duì)內(nèi)部變量值的改變是否會(huì)影響外部變量呢当船,這里我們用具體的例子來(lái)分析一下。
function addTen(num) {
num += 10;
return num;
}
var count = 20;
var result = addTen(count);
alert(count); //20 沒(méi)有改變
alert(result); //30
我們可以看到默辨,基本類型變量的傳參對(duì)原變量并無(wú)影響德频,這一點(diǎn)大家也容易理解∷跣遥可是對(duì)引用類型的傳參呢壹置?
// eg3.1
function setName(obj) {
obj.name = "Nicholas";
}
var person = new Object();
setName(person);
alert(person.name); //"Nicholas"
我們發(fā)現(xiàn)原始變量person對(duì)象的name屬性被改變了,這具有很強(qiáng)的迷惑性表谊,會(huì)讓人以為引用類型的傳參是將整個(gè)引用對(duì)象存儲(chǔ)的內(nèi)容復(fù)制傳遞了钞护。是否如此呢?我們看下面這個(gè)例子爆办。
// eg3.2
function setName(obj) {
obj.name = "Nicholas";
obj = new Object();
obj.name = "Greg";
}
var person = new Object();
setName(person);
alert(person.name); //"Nicholas"
如果真的是按引用傳遞难咕,那么最后person.name應(yīng)該是'Greg'才對(duì),但事實(shí)上卻是'Nicholas'距辆,說(shuō)明這里是并不是按引用傳遞步藕。下面我們來(lái)一步步分析這兩段代碼的實(shí)際過(guò)程。
對(duì)于eg3.1和eg3.2:
step1: var person = new Object();執(zhí)行完如下:
step2: 進(jìn)入setName(person);如下:
step3: obj.name = "Nicholas";執(zhí)行完如下:
eg3.1的setName函數(shù)調(diào)用到此已結(jié)束挑格,此時(shí),person.name從圖中可以看出是'Nicholas'沾歪。而對(duì)于eg3.2漂彤,其setName函數(shù)增加了兩個(gè)步驟,如下:
step4: obj = new Object();執(zhí)行完如下:
step5: obj.name = "Greg";執(zhí)行完如下:
可以看到灾搏,此時(shí)person.name仍然是'Nicholas'挫望。
現(xiàn)在,我們明白了狂窑,其實(shí)JS函數(shù)參數(shù)的傳遞始終是按值傳遞媳板。但是在函數(shù)調(diào)用的過(guò)程中,我們到底是對(duì)該值指向的堆地址進(jìn)行了操作泉哈,還是對(duì)該值進(jìn)行了操作蛉幸,決定了我們是否會(huì)對(duì)原變量產(chǎn)生影響。
4. 測(cè)試一下
看到這里丛晦,你應(yīng)該已經(jīng)掌握了JS的數(shù)據(jù)類型和按值傳遞奕纫。來(lái)做一個(gè)小測(cè)驗(yàn),下面是兩個(gè)對(duì)數(shù)組進(jìn)行拼接并返回拼接后數(shù)組的函數(shù)烫沙,哪個(gè)函數(shù)在拼接的同時(shí)對(duì)傳入的參數(shù)也產(chǎn)生了影響呢匹层?(順便學(xué)習(xí)一下es6的知識(shí)吧b( ̄▽ ̄)d)
var fillArray = (arr, ...values) => {arr.push(...values);return arr;}
var fillArray = (arr, ...values) => {arr = arr.concat(...values);return arr;}
參考
BOOK-《JavaScript高級(jí)程序設(shè)計(jì)(第3版)》 第3章