請寫出如下代碼運行的結果並解釋為什么?[代碼]
var type = 'images'; var size = {width: 800, height: 600}; var format = ['jpg', 'png']; function change(type, size, format){ type = 'video'; size = {width: 1024, height: 768}; format.push('map'); } change(type, size, format); console.log(type, size, format);
最后的打印結果為:images { width: 800, height: 600 } [ 'jpg', 'png', 'map' ]
;
實際上就是函數形參的傳遞根據實參值的類型分為值復制(對應基本類型)和引用復制(對應引用類型);
通過值復制的值無論怎么改變都不會影響原來的值(對應type
變量的情況),而通過引用復制的值改變后原值也會改變(對應format
變量的情況),但是直接改變引用本身並不會影響其他引用(即引用另一個引用類型的值時,原值的其他引用不會改變;對應size
變量的情況);
參考:《你不知道的JavaScript(中卷)2.5小節》
type 與size,在執行上下文中,因為是形參,活動對象會創建type、size兩個屬性,並被賦值,函數的參數,本質是傳值。type與size在活動對象中,一開始被賦值 ‘images'、‘{width: 800, height: 600}’,后來又被重新改寫,
不影響全局的變量,format 一開始初始化時,同sise、type,但是在format不是重新賦值操作,是在原來的基礎上,修改了原數組。
var type = 'images'; // 基礎類型 var size = {width: 800, height: 600}; // 引用類型 var format = ['jpg', 'png']; // 引用類型 // js 以函數作為作用域,定義在函數內部的變量與外部的變量相互不影響 function change(type, size, format){ // 函數接受了三個參數,在函數生成上下文的時候,會先進行變量的聲明和提升 // 盡管與全局變量名稱相同,但是是互不影響的 // var type = type; // var size = size; // var format = format; // 對變量進行賦值 // 由於作用域的關系,會先找到定義在 change 中的 type,而非全局的 type // 如果在 change 中沒有定義過 type 即沒有作為參數的話,則這么賦值會影響全局的 type type = 'video'; // 同樣對 change 內的 size 進行賦值,這里賦的是 size 的引用地址,實際與全局的 size 指向同一個對象 // 所以如果進行了 size.dpi = 666 類似的操作,就會影響到全局的 size size = {width: 1024, height: 768}; // format 是引用類型,因此指向的內存引用與全局的相同 // 所以 push 方法會對全局的 format 產生影響 format.push('map'); } change(type, size, format); console.log(type, size, format); // 'images', {width:800, height:600}, ['jpg', 'png', 'map']