JavaScript修改範圍外變數的方法,javascript域外
1.今天在看JavaScript學習指南的時候做的課後習題,也因此詳細的對函數的傳入參數進行比較深入的研究.
題目如下:
函數如何才能修改其範圍之外的變數?編寫一個函數,由1~5的數字組成的數組作為參數,調用該函數後將把其中的數字項替換為相應的字串表示形式.
需要注意知識點:
在JavaScript中函數參數的傳遞,對於基於原始值的參數進行值傳遞(數字,字串,布爾值),函數中的修改不會影響實際參數值.而傳遞給函數的參數而言,對象是一個引用,對其的修改的將會反映在主調程式中.<-但是,會有這樣的情況,如下
var outer_number = ;var outer_boolean = true;var outer_array = [,,];var outer_object = {test:""};function display(num,bool,arr,obj){console.log("number:"+num+"\nboolean:"+bool+"\narray:"+arr+"\nobject:"+obj.test);}function test(num,bool,arr,obj){display(num,bool,arr,obj);//num=,bool=true,array=[,,],object.test=num = ;bool = false;arr[] = ;obj.test = "";display(num,bool,arr,obj);//num=,bool=false,array=[,,,],object.test=arr = [,,];obj = {test:""};display(num,bool,arr,obj);//num=,bool=false,array=[,,],object.test=}test(outer_number,outer_boolean,outer_array,outer_object);display(outer_number,outer_boolean,outer_array,outer_object);//num = ,bool=true,array=[,,,],object.test=
在上面代碼中我們建立了4個全域變數,類型分別為數字,布爾值,數組,對象.2個函數,display和test.
display執行了4次,分別結果如下:
"number:2
boolean:true
array:1,2,3
object:122"<-傳入函數時的值
"number:0
boolean:false
array:1,2,3,3
object:134"<-執行更改
"number:0
boolean:false
array:3,2,1
object:133"<-重新賦值
"number:2
boolean:true
array:1,2,3,3
object:134"<-函數執行完畢後
可以看出我們對數組和對象的重新賦值並沒有成功,如果按引用傳遞,那麼我們應該也對全域變數的數組和對象重新賦值修改了呀.
其實JavaScript中所謂的按引用賦值並不是真正意義上的按引用複製,準確說應該是按共用傳遞.也可以叫按對象傳遞,按對象共用傳遞(call by sharing).
在這個按共用傳遞的條件下,我們擷取的引用可以說只是實參引用的副本,它和我們經常說的按引用傳遞的最大差別就在於我們在對引用副本的賦值不會影響實參的值,正如我們上面那樣做的那樣,賦值操作是不可行的.
當然我們從物件類型和基本類型兩方面看,對象是可變的而基本類型是不可變的(注意!字串修改其實是返回的新的字串),所以按共用傳遞對於基本類型來說也是符合按共用傳遞的.
總結一下:
JavaScript中,基本類型和對象都按共用傳遞(call by sharing),但是由於JavaScript的基本類型的不變性,基本類型按共用傳遞與按值傳遞沒有任何區別,而對象按共用傳遞.
按共用傳遞(call by sharing):傳遞的是實參引用的副本,我們對引用副本的賦值不影響實參的值,但是可以使用引用副本去修改引用的內容.詳細的wiki地址
函數對傳入的參數:
1.基本類型,按值傳遞(或者也可以說按共用傳遞),內部賦值修改都不影響主調程式
2.物件類型,按共用傳遞,傳入的為實參引用的副本,內部對該引用的賦值無效,對對象屬性的賦值修改有效.
大概就是這麼理解了,假如有什麼地方我犯了什麼錯誤,也希望能被指出來.
下面單獨拉出JavaScript範圍
任何程式設計語言都有範圍的概念,簡單的說,範圍就是變數與函數的可存取範圍,即範圍控制著變數與函數的可見度和生命週期。在JavaScript中,變數的範圍有全域範圍和局部範圍兩種。
全域範圍(Global Scope)
在代碼中任何地方都能訪問到的對象擁有全域範圍,一般來說以下幾種情形擁有全域範圍:
(1)最外層函數和在最外層函數外面定義的變數擁有全域範圍,例如:
var authorName="山邊小溪";function doSomething(){var blogName="夢想天空";function innerSay(){alert(blogName);}innerSay();}alert(authorName); //山邊小溪alert(blogName); //指令碼錯誤doSomething(); //夢想天空innerSay() //指令碼錯誤
(2)所有末定義直接賦值的變數自動聲明為擁有全域範圍,例如:
function doSomething(){var authorName="山邊小溪";blogName="夢想天空";alert(authorName);}doSomething(); //山邊小溪alert(blogName); //夢想天空alert(authorName); //指令碼錯誤
變數blogName擁有全域範圍,而authorName在函數外部無法訪問到。
(3)所有window對象的屬性擁有全域範圍
一般情況下,window對象的內建屬性都擁有全域範圍,例如window.name、window.location、window.top等等。
1. 局部範圍(Local Scope)
和全域範圍相反,局部範圍一般只在固定的程式碼片段內可訪問到,最常見的例如函數內部,所有在一些地方也會看到有人把這種範圍稱為函數範圍,例如下列代碼中的blogName和函數innerSay都只擁有局部範圍。
function doSomething(){var blogName="夢想天空";function innerSay(){alert(blogName);}innerSay();}alert(blogName); //指令碼錯誤innerSay(); //指令碼錯誤
您可能感興趣的文章:
- JScript中的''var''定義變數的範圍
- 關於javascript 回呼函數中變數範圍的討論
- 理解JavaScript變數範圍更輕鬆
- JavaScript的變數範圍深入理解
- 有關js的變數範圍和this指標的討論
- javascript中的範圍scope介紹
- js使用函數綁定技術改變事件處理常式的範圍
- js變數以及其範圍詳解
- 淺談javascript中的範圍
- 深入理解JavaScript系列(14) 範圍鏈介紹(Scope Chain)
- JavaScript中的範圍鏈和閉包
- 關於JS管理範圍的問題
- 淺談angularJS 範圍