(1)值型別(基本型別):字串(string)、數值(number)、布林值(boolean)、undefined、null (這5種基本資料型別是按值訪問的,因為可以操作儲存在變數中的實際的值)(ecmascript 2016新增了一種基本資料型別:symbol )
(2)引用型別:物件(object)、陣列(array)、函式(function)
(1)值型別:
1、占用空間固定,儲存在棧中(當乙個方法執行時,每個方法都會建立自己的記憶體棧,在這個方法內定義的變數將會逐個放入這塊棧記憶體裡,隨著方法的執行結束,這個方法的記憶體棧也將自然銷毀了。因此,所有在方法中定義的變數都是放在棧記憶體中的;棧中儲存的是基礎變數以及一些物件的引用變數,基礎變數的值是儲存在棧中
,而引用變數儲存在棧中的是指向堆中的陣列或者物件的位址
,這就是為何修改引用型別總會影響到其他指向這個位址的引用變數。)
2、儲存與複製的是值本身
3、使用typeof檢測資料的型別
4、基本型別資料是值型別
(2)引用型別:
1、占用空間不固定,儲存在堆中(當我們在程式中建立乙個物件時,這個物件將被儲存到執行時資料區中,以便反覆利用(因為物件的建立成本通常較大),這個執行時資料區就是堆記憶體。堆記憶體中的物件不會隨方法的結束而銷毀,即使方法結束後,這個物件還可能被另乙個引用變數所引用(方法的引數傳遞時很常見),則這個物件依然不會被銷毀
,只有當乙個物件沒有任何引用變數引用它時,系統的垃圾**機制才會在核實的時候**它。)
2、儲存與複製的是指向物件的乙個指標
3、使用instanceof檢測資料型別
4、使用new()方法構造出的物件是引用型
例項:
//console.log(person instanceof object); // 變數 person 是 object 嗎?值型別:number、string、bollean、undefined
var a = 100
var b =a
a = 200console.log(b)
//100 儲存與複製的是值本身
//引用型別:物件、陣列、函式、null(空指標)
//可以擴充套件屬性
var a =
var b =a
b.age = 21 console.log(a.age)
//21
// 利用typeof來區分
typeof undefined //
undefined
typeof 'abc' //
string
typeof 123 //
number
typeof
true
//boolean
//typeof 區分不出來引用型別(除了函式)
typeof {} //
object
typeof //
object
typeof
null
//object
typeof console.log //
function
// 用instanceof來區分引用型別
// 如果變數是給定引用型別(根據它的原型鏈來識別)的例項,那麼instanceof 操作符就會返回 true。
console.log(colors instanceof array); // 變數 colors 是 array 嗎?
console.log(pattern instanceof regexp); // 變數 pattern 是 regexp 嗎?
(1)動態的屬性:定義基本型別值和引用型別值的方式是類似的。但是,當這個值儲存到變數中以後,對不同型別值可以執行的操作則大相徑庭。對於引用型別的值,我們可以為其新增屬性和方法,也可以改變和刪除其屬性和方法,但是,我們不能給基本型別的值新增屬性,只能給引用型別值動態地新增屬性,以便將來使用。例如
var person = new(2)複製變數值:如果從乙個變數向另乙個變數複製基本型別值,會在變數物件上建立乙個新值,然後把該值複製到為新變數分配的位置上。object();
person.name = "nicholas";
alert(person.name);
//"nicholas"
var num1 = 5;上述例子中,num1儲存的值是5,當使用 num1 的值來初始化 num2 時,num2 中也儲存了值 5。但 num2中的 5 與 num1 中的 5 是完全獨立的,該值只是 num1 中 5 的乙個副本。此後,這兩個變數可以參與任var num2 = num1
何操作而不會相互影響。
複製基本型別的過程:
當從乙個變數向另乙個變數複製引用型別的值時,同樣也會將儲存在變數物件中的值複製乙份放到
為新變數分配的空間中。不同的是,這個值的副本實際上是乙個指標,而這個指標指向儲存在堆中的乙個物件。複製操作結束後,兩個變數實際上引用同乙個物件。因此,改變其中乙個變數,就會影響另外乙個變數:例
var obj1 = new首先,變數 obj1 儲存了乙個物件的新例項。然後,這個值被複製到了 obj2 中;換句話說,obj1和 obj2 都指向同乙個物件。這樣,當為 obj1 新增 name 屬性後,可以通過 obj2 來訪問這個屬性,因為這兩個變數引用的都是同乙個物件。object();
var obj2 =obj1;
obj1.name = "nicholas";
alert(obj2.name);
//"nicholas"
複製值型別的過程如下圖:
(3)傳遞引數:在向引數傳遞基本型別的值時,被傳遞的值會被複製給乙個區域性變數(即命名引數,或者用ecmascript 的概念來說,就是 arguments 物件中的乙個元素)。在向引數傳遞引用型別的值時,會把這個值在記憶體中的位址複製給乙個區域性變數,因此這個區域性變數的變化會反映在函式的外部。
function在函式內部,引數 num 的值被加上了 10,但這一變化不會影響函式外部的 count 變數。引數num 與變數 count 互不相識,它們僅僅是具有相同的值。addten(num)
var count = 20;
var result =addten(count);
alert(count);
//20,沒有變化
alert(result); //
30
function為了證明物件是按值傳遞的,我們再看一看下面這個經過修改的例子:setname(obj)
var person = new
object();
setname(person);
alert(person.name);
//"nicholas"
function如果 person 是按引用傳遞的,那麼 person 就會自動被修改為指向其 name 屬性值為"greg"的新物件。但是,當接下來再訪問 person.name 時,顯示的值仍然是"nicholas"。setname(obj)
var person = new
object();
setname(person);
alert(person.name);
//"nicholas"
這說明即使在函式內部修改了引數的值,但原始的引用仍然保持未變。實際上,當在函式內部重寫 obj 時,這個變數引用的就是乙個區域性物件了。而這個區域性物件會在函式執行完畢後立即被銷毀。
//字串拼接
var a = 100 + 10 //
100var b = 100 + '10' //
10010
//== 運算子
100 == '100' //
true
0 == '' //
true
null == undefined //
true
//語句
var a = true
if(a){}
var b = 100
if(b){} //
把數字轉換為true
var c = ''
if(c){} //
把空字串轉換為false
//邏輯運算
console.log(10&&0); //
0 把10轉換成true
console.log('' || 'abc'); //
'abc' 把空字串轉換為false
console.log(!window.abc); //
window.abc是undefined 把非undefined轉換成true
//判斷乙個變數會被當做true還是false
var a = 100console.log(!!a); //
true
js 中的值型別和引用型別
j ascript中值型別 基本型別 number,string,bool,undefined,null 這5種基本資料型別是按值訪問的,因為可以操作儲存在變數中的實際的值 引用型別 物件 object 陣列 array 函式 function 2.值型別和引用型別的區別 1 值型別 1 占用空間固...
JS值型別和引用型別資料的區別
最近真的閒啊,沒事做,寫了一大堆前端技術部落格,越寫就越覺得自己菜,知道的少,每天這麼高產的部落格量,隨便上網晃悠一下,就又能發現乙個我不知道的或者也不太清楚的基本概念.so 又一篇暴露js水平的部落格誕生。我也解釋不好,也比較懶,隨手存兩篇我覺得非常不錯的部落格 幫助自己理解 js高階程式設計給的...
值型別和引用型別的區別
在開始 net framework的底層型別系統時,常常會聽到一些相互矛盾的說法。一方面,所有的型別都繼承於object類 另一方面 在值型別和引用型別之間轉換時要特別小心 搞清楚這些說法的關鍵在於,要記住 每種型別,無論是內建的結構,如整型或字串型,還是定製類,如myemployee,都繼承於ob...