JavaScript 引用型別
所謂引用型別,在ECMAScript
中表示一種資料結構,其中有一些資料和方法,在其他語言中大多被稱為類
,但是在這裡我們一般不這樣稱呼。即使ECMAScript
是一門面向物件語言,但是它不具備傳統面嚮物件語言中所支援的類和介面。他們描述的是一類物件所具有的屬性和方法。引用型別的值就是一個物件,它是引用型別的一個例項。
新物件是用一個new
操作符後面跟上一個建構函式建立的。所謂建構函式本質上是一個函式,這個函式的目的是為了建立某一類物件,函式中包含了建立該物件所需要的東西。ECMAScript
中提供其他各種型別的引用型別。
基本型別和引用型別的值
JavaScript 中的變數與其他語言的變數有很大差別,獨特的鬆散型別的特性,決定了它只是特定時間用來儲存特定值的一個名字而已。它的資料型別在生命週期中是可以隨時改變的。Crazy and Powerful !
在一個變數中可能存在兩種不同資料型別的值:基本型別值和引用型別值。基本型別值是按值引用的,我們可以操作儲存在變數中實際的值。但是引用型別就不同了,引用型別的值是儲存在記憶體中的物件,而JavaScript
是不允許直接操作記憶體空間的。所以說我們在操作物件的時候操作的是物件的引用而不是實際的物件。所以物件是按引用訪問的。
- 引用型別具有動態的屬性
兩種型別在定義的時候是相似的,建立一個變數並且為它賦值。但是引用型別允許我們更改其屬性和方法,而基本型別值沒有這個功能。當我們為基本型別值增添屬性後雖然不會報錯,但是卻是無效的。
- 變數值的複製
對於基本型別值來說,從一個變數複製給另一個變數的時候,會在新的變數上建立一個新值,然後把值複製過去。從此這兩個值就沒了聯絡,不會相互影響了。但如果是從一個變數向另一個變數複製引用型別的值的時候,複製過去的其實是一個指標,指向存在堆中的一個物件,然後兩個變數引用同一個物件,改變一個,會影響另一個:
let obj1 = new Object(); let obj2 = obj1; obj1.name = 'Baoyuan'; console.log(obj2.name); //'Baoyuan' 複製程式碼
- 引數的傳遞
ECMAScript
中所有函式的引數都是按值傳遞的。
向函式傳遞基本型別的值的時候,被傳遞的值被複制給命名引數。而對於引用型別來說,會把這個值在記憶體中的地址複製給命名引數,這會導致函式內值的改變反應在函式外部:
function setName (obj) { obj.name = 'Baoyuan'; }; let people = new Object(); setName(people); // 將people物件地址複製給了函式內部的obj,也就是說引用同一個物件。 console.log(people.name); //'Baoyuan' 複製程式碼
即使這個物件是按值傳遞的,因為 people 指向的物件在堆記憶體中只有一個, obj 會按引用來訪問同一個物件。
我們先來看最常見用的最多的一種-Object
。
Object
Object
是典型的引用型別值,雖然它的例項中並不具備很多功能,但是大多數我們所見的引用型別值都是他的例項。而且對於我們在程式中儲存和傳輸資料來說是不可或缺的。
通常我們可以使用new
方法來建立一個物件:
let peopele = new Object(); people.age = 23; people.name = 'Baoyuan'; 複製程式碼
我們建立了一個people
物件併為其設定了姓名和年齡屬性,同樣的使用物件字面量也可以有相同的效果:
let people = { name: 'Baoyuan', age: 23 }; 複製程式碼
在使用這種方式的時候屬性名也可以用字串表示,一般我們推薦使用字面量建立,它的程式碼簡潔而且它也是向函式傳遞大量引數的首選方式。 我們可以通過點訪問法訪問其屬性:
console.log(people.name); //Baoyuan 複製程式碼
除此之外還有一種更為靈活的方式,當我們的屬性名中含有包含會導致語法錯誤的字串或者是保留字的話,我們可以使用[]
來訪問:
people['name'] = 'Bao yuan'; //屬性名以字串形式放入,屬性值中含有空格。 複製程式碼
這種方式還可以通過變數來訪問屬性:
let item = 'name'; people[item]; //Baoyuan 複製程式碼
同常來說除非必須使用[]
的情況下,一般建議用點表示法。
除此之外引用型別還有Array
、Date
、RegExp
、Function
等。
型別判斷
在檢測基本資料型別的時候我們使用typeof
但是如果我們在引用型別上使用的話都會返回object
,這並不是我們想要的。為此ECMAScript
提供了instanceof
:
result = variable instanceof constructor
它會根據原型鏈來識別,比如:
console.log(people instanceof Array); //變數people是Array型別嗎? 複製程式碼
不足之處請批評指正~