【追尋javascript高手之路01】javascript參數知多少?


前言

我最近在思考一個問題,我本身平時還是積累了不少東西,面試時候問的東西基本逃不出寫的博客(當然,高級階段的就不行了),但是真的被問到時我卻不一定答得上來。

知道且能回答,回答的效果都不是很好。。。。這是一個讓人很囧的事情,另外,按道理說阿里面試是完蛋了,后面再慢慢找工作吧,休息一下也不錯的。

除了記憶力意外,心態也是一個問題,比如我最常說的一句話就是:

恩,你說這個我知道,我還特意學習過,寫了demo,但是給忘了!!!

哎喲,我聽到這句話都可恥的笑了,你忘了和我有一毛線關系?忘了是很多原因造成的,最直接原因應該是不夠深刻,所以最近我們便拋開其它雜念,由最基礎的HTML+CSS+Javascript學習吧。

這次學習,希望能給各位以及自己帶來不一樣的感覺,由於最近要出去面試,問的最多的恐怕是javascript,所以我們先看看js了,這次學習中我把一些平時了解得似是而非的東西都給揪出來看看。

函數參數

各位看得沒錯,我覺得我對函數的參數理解不夠徹底,各位怎么樣呢,我現在出個例子來試試:

1 var param = { name: '葉小釵', age: 33 };
2 function alertArgurment(d) {
3     for (var k in d) {
4         alert(k + ': ' + d[k]);
5     }
6 }
7 alertArgurment(param);

這個題自然沒有問題,那我們變化一下呢?

1 var param = { name: '葉小釵', age: 33 };
2 function alertArgurment(param) {
3     for (var k in param ) {
4         alert(k + ': ' + param [k]);
5     }
6 }
7 alertArgurment(param);

各位現在知道自己使用的是外面的param還是里面的param呢?若是仍然難不倒你,看看這個呢:

1 var param = { name: '葉小釵', age: 33 };
2 function alertArgurment(d) {
3     param.id = '刀狂劍痴';
4     for (var k in d) {
5         alert(k + ': ' + d[k]);
6     }
7 }
8 alertArgurment(param);

那么這個呢?或者說這段代碼與這段代碼有什么不同呢?請對比兩段代碼:

1 var param = { name: '葉小釵', age: 33 };
2 function alertArgurment(d) {
3     d.id = '刀狂劍痴';
4     for (var k in d) {
5         alert(k + ': ' + d[k]);
6     }
7 }
8 alertArgurment(param);

怎么樣呢?對於參數各位還敢說知道嗎,我反正有點不敢了,於是再看看各位知道下面這些家伙是干什么的嗎?

① arguments
② callee
③ caller

若是你都知道並且了解十分深入的話,那么我又在自己為難自己了。。。。好了,上面的問題先留着,我們來看看什么是參數:

ECMAScript函數的參數與其它語言有所不同,其有以下特點:
① 個數不限
② 類型不限
③ 函數調用時候參數傳遞看心情

ECMAScript在內部是使用一個數組來表示參數的:arguments對象可訪問這個數組。

但是arguments只是與數組類似,他並不是Array的實例,所以我們定義函數時候可以不顯示定義參數而是使用arguments[0]的方式讀取
於是函數重載什么的也只能是傳說了。

callee:函數內部有兩個特殊對象,一個是this一個是arguments,其中arguments有一個callee的屬性,他是一個指針,指向其函數。

在ECMAScript5中規范化了另外一個函數對象屬性:caller,這個屬性保存着調用當前函數的引用,全局變量中對應着null
其獲取方式為arguments.callee.caller(在嚴格模式先訪問arguments.callee要報錯)

我們先貼一張圖出來看看:

各位看到了,我們只是將param作為參數傳了進去,然后在里面給他多加了一個屬性,但是param也多了一個屬性哦!

--------------華麗的分割線------------------

PS:我突然想起了那天面試我錯了一道非常惡心的題,突然想起的,勿噴,實在太惡心了。。。

1 var a = {};
2 a.a = 6;
3 alert(a.a);
4 
5 var b = a;
6 b.a = 66;
7 alert(a.a);

這個我還答對了,但是好像后面類似這樣的題我答錯了,囧:

1 var a = 3;
2 alert(a);
3 a = 4;

就是類似於這樣的題了,我當時是餓了還是在大神面前智商降低了呢?我剛剛突然想起了,覺得好戳哦。。。

--------------華麗的分割線------------------

回到本題,我們來理一理這個東西,我們這里傳遞了一個對象作為函數的參數,與其說是對象,不如說是對象的引用

ECMAScript所有參數傳遞的都是值,不能通過引用傳遞參數

所以內部改變了那個值也會改變外面的東東,但是傳遞值的話又有所不同:

1 var a = 1;
2 function alertArgurment(d) {
3     d = 2;
4     alert(d);
5 }
6 alertArgurment(a);

這塊里面就是2,外面的a仍然是1了。根據前面的研究我們再修改下程序:

 1 var param = { name: '葉小釵', age: 33 };
 2 function alertArgurment(d) {
 3     d.id = '刀狂劍痴';
 4     arguments[0].qq = '素還真';
 5     for (var k in d) {
 6                 alert(k + ': ' + d[k]);
 7     }
 8 }
 9 alertArgurment(param);
10 var s = '';

我們既然不能傳遞引用,那么他就直接將對象傳進去了。。。

1 var param = { name: '葉小釵', age: 33 };
2 function alertArgurment(d) {
3     var tmp = param;
4     d.id = '刀狂劍痴';
5     arguments[0].qq = '素還真';
6     var sss = '';
7 }
8 alertArgurment(param);

大家請設置斷點觀察tmp的變化,d變化了tmp會與之同步,所以我們這里應該是把param直接給傳遞進去了吧:

整理

ECMAScript中所有函數的參數都是按值傳遞。在這點上我們容易模糊,因為引用類型傳遞的時候會完全的復制進去

在傳遞引入引用類型時,會把這個值在內存中的地址復制給一個局部變量,這個局部變量的變化會反應到外部。
就如我們上面的例子:
① 我們創建了一個對象param
② 我們將之轉到函數內部后就復制給了d對象(arguments[0]),d與param現在是同一對象,他們在堆中只有一個對象。

 

結語

好了,我們隊參數的研究暫時到這里,若您有何疑問請提出


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM