js個性
js有一些“神奇”特性。
1.函數參數
js的函數在定義的時候可以沒有參數,但調用的時候傳參也不會報錯,也就是說函數參數的定義與函數實際調用沒有半毛錢關係。之所以會這樣,是因為ECMAScript中的參數在內部是用一個數組表示的。舉個例子:
function add(){ if(arguments.length == 1){ alert(arguments[0]); }else if(arguments[1].length == 2){ alert(arguments[1] +arguments[0]); } }
當調用add(10)的時候直接輸出10,調用add(10,20)的時候輸出30.情況就是這樣,不管你怎麼傳參,函數接收到的實際上是一個arguments數組。當然你也可以使用參數。一開始還以為js讓第i個參數和arguments[i-1]指向了同一塊內存空間。但事實上並非如此。他們的內存空間是獨立的,隻是arguments對象中的值會自動反應到對應的命名參數罷了。
2.沒有重載
如果你定義了兩個同名的函數,那麼後一個函數很可能會覆蓋前麵的。其實還是之前說的問題。js函數是通過arguments對象操作參數的,你有定義多少參數都沒意義,關鍵是你調用時傳遞多少參數。而函數的重載是通過同名參數的類型和數量來實現的,所以這就決定了js中沒有傳統意義上的重載。但你可以通過檢查傳入參數的個數和類型來模仿重載。就像上麵的add()函數一樣。有沒有感覺這樣還要簡單一些?
3.基本類型和引用類型
js中的五種基本類型:Undefinded、Null、Boolean、Number和String,他們都是按值訪問的。引用類型的值是保存在內存中的對象,由於js不準直接訪問內存中的位置,所以在操作對象時,實際上是在操作對象的引用。但當為對象添加屬性時,操作的是實際的對象。所以如果當從一個變量向另外一個變量複製引用類型的值時,對一個變量修改屬性,也會反映到另外一個變量身上,因為他們在堆內存中指向的是同一個對象。
var obj1=new Object(); var obj2=obj1; obj1.name="Lee"; alert(obj2.name);//彈出"Lee"
4.所有函數參數都是按值傳遞的!
先看一個例子:
function setName(obj){ obj.name="Lee"; } var person=new Object(); setname(person); alert(person.name);//彈出"Lee"不是按值傳遞麼!為毛在函數內改變值函數外也會受影響!好吧,其實在傳遞參數給setname函數的時候複製了person變量,上麵說了,這兩個變量指向的是內存中的同一個對象,所以改變一個另外一個也會變!有很多人錯誤的以為:在局部作用域中修改的對象在全局作用域中反應出來就說明參數是按引用傳遞的。為了證明對象也是按值傳遞的,再看一個例子:
function setName(obj){ obj.name="Lee"; obj = new Object(); obj.name = "Yu"; } var person=new Object(); setname(person); alert(person.name);//彈出"Lee"如果person是按引用傳遞的,那麼彈出的應該是Yu,而不是Lee。實際上在setname中對obj重寫之前,obj與person指向的是同一個對象,重寫之後,obj就是一個局部對象了,這個對象在函數執行完畢後被立即銷毀。
5.沒有塊級作用域
最後更新:2017-04-03 12:53:49