JS變量可能包含兩種不同數據類型的值;基本類型值和引用類型值。基本類型指的是簡單的數據段,而引用類型值那些由多個值構成的對象;
在將一個值賦給變量時,解析器必須確定這個值是基本類型值還是引用類型值。JS有5種基本數據類型:Undefined,
Null,Boolean,Number和String。這5種基本數據類型是按值訪問的。因為可以操作保存在變量中的實際的值。
引用類型的值保存在內存中的對象。與其他語言不同,JavaScript不允許直接訪問內存中的位置,也就是說不能直接操作對象的內存空間。在操作對象時,實際上是在操作對象的引用而不是實際的對象,為此,引用類型的值是按引用訪問的。引用是js面向對象的基本概念之一。它是一個指向對象實際位置的指針。實際的對象肯定不會是引用。比如字符串永遠是字符串,不過多個變量能夠指向同一個對象。
對象可以中有多個原型屬性(property)
動態的屬性
定義基本類型值和引用類型值的方式是類似的:創建一個變量并為該變量賦值。但是,當這個值保存到變量中以后,對不同類型值可以執行的操作則很相同。對于引用類型的值,我們可以為其添加屬性和方法每頁可以移除改變和刪除其屬性和方法。
~~~
var person=new Object();
person.name="張三";
alert(person.name);
var name="李四";
name.age="13";
alert(name.age);
~~~
以上代碼創建了一個對象將其保存在了變量person中。然后,我們為該對象添加了一個名字為name的屬性,并為這個屬性賦了值,當我打印這個屬性的時候,是可以得到結果的。這說明如果對象不被銷毀或者這個屬性不被刪除,則這個屬性將一直存在。但是我們不能給基本數據類型添加屬性。
復制變量值:
除了保持的方式不同之外,在從一個變量向另一個變量復制基本類型和引用類型的值時,也存在不同。如果從一個變量向另一個變量復制基本類型的值,會在變量對象上創建一個新值,然后把該值復制到位新變量分配的位置上;
~~~
var num1=5;
var num2=num1;
num1=3;
alert(num2);
~~~
在此num1種保存的值是5.當使用num1的值來初始化num2時,num2中也保存了值5。但num2中的5與num1中的5是完全獨立的。該值只是num1中5的一個副本。此后,這兩個變量可以參與任何操作互不影響。我覺得這一點和其他高級語言很相似例如java。
當從一個變量向另一個變量復制引用類型的值時,同樣也會將存儲在變量對象中的值復制一份到為新變量分配的空間中。不同的是們這個值的副本實際上是一個指針,而這個指針指向存儲在堆中的一個對象,復制操作結束后,兩個變量實際上將引用同一個對象。因此,改變其中一個變量,就會影響到另一個變量。這個跟引用類型的存儲位置有關。
~~~
var obj1=new Object();
var obj2=obj1;
obj1.name="張三";
alert(obj2.name);
~~~
打印出來的是張三,這是因為obj1和obj2是兩個引用,這兩個引用指向的值都是Object();我們操作值的時候是通過引用的,當我們的對象發生改變的,其引用的值也發生了改變;
傳遞參數:
JS中所有函數的參數都是按值傳遞的。Java里面的參數有人認為是按值傳遞的,有人認為是按參數傳遞的,不過我寫過一遍博客,里面專門討論過這個,Java其實是按值傳遞的。也就是說,把函數外部的值復制給函數內部的參數,就和把值從一個變量復制到另一個變量一樣。基本類型值的傳遞如同基本類型變量的復制一樣,而引用變量傳遞也和復制一樣。
在向參數傳遞基本類型的值時,被傳遞的值會被復制給一個局部變量(即命名參數,用JS的概念來說,就是arguments數組中的一個元素)。在向參數傳遞引用類型的值時,會把這個值在內存中的地址復制給一個局部變量,因此這個局部變量的變化會反映在函數的外部。
~~~
function add(num){
num+=10;
return num;
}
var count=20;
var resule=add(count);
alert(resule);
alert(count);
~~~
參數count和參數num互不影響,只是num復制了count的值而已;
~~~
function setName(obj){
obj.name="張三";
}
var person=new Object();
setName(person);alert(person.name);
~~~
以上代碼創建了一個對象,并將其值保存在person引用中,然后調用setName函數,把值傳遞給obj,obj這個時候引用的對象和person引用的對象是同一個對象,所以里面修改了屬性值,外面會有顯示。有很多程序員錯誤的認為,在局部作用域中修改的對象會在全局作用域中反映出來,就說明是按引用傳遞的,這個說法不現實;
~~~
function setName(obj){
obj.name="張三";
obj=new Object();
obj.name="李四";
}
var person=new Object();
setName(person);alert(person.name);
~~~
如果是按引用傳遞的話,我們為這個引用重新創建了一個對象,并賦值,但是最后的結果還是張三,證明了是按值傳遞的;
- 前言
- javascript基礎與定義
- JavaScript變量
- JavaScript變量二(數據類型,Number,String,Object)
- JavaScript傳參的問題
- JavaScript基本類型和引用類型的值
- JavaScript執行環境及作用域
- JavaScript垃圾收集
- JavaScript和JQuery和angularjs操作select
- 搞對象前,你得先有對象
- JavaScript數組
- JavaScript運行原理解析
- Jquery和angularjs獲取check框選中的值小技巧
- JavaScript函數表達式
- JavaScript的閉包理解
- JavaScript BOM
- JavaScritpt的DOM初探之Node(一)
- 為什么說DOM操作很慢
- jQuery性能優化