大多數(shù)的開發(fā)者在使用Java或C#等基于類的語言的過程中學(xué)會(huì)了面向?qū)ο缶幊?。由于JavaScript沒有對(duì)類的正式支持(當(dāng)然ES2015支持了),這些開發(fā)者在學(xué)習(xí)JavaScript時(shí)往往會(huì)迷失方向。JavaScript不需要在開頭就定義好各種類,你可以在寫代碼過程中根據(jù)需要?jiǎng)?chuàng)建數(shù)據(jù)結(jié)構(gòu)。由於JavaScript缺少類,也就缺少用於對(duì)類進(jìn)行分組的包。在Java中,包和類的名字不僅定義了對(duì)象的類型,也在工程中列出文件和目錄的層次結(jié)構(gòu),JavaScript編程就好像從一塊空白石板開始:你可以在上面組織任何你想要的東西。有些開發(fā)者選擇模仿其他語言的結(jié)構(gòu),也有一下人則利用JavaScript的靈活性來創(chuàng)建一些新的東西,對(duì)沒有掌握J(rèn)avaScript的人來說,這種選擇的自由令人崩潰,然而你一旦熟悉了它,你會(huì)發(fā)現(xiàn)JavaScript是一個(gè)無比靈活的語言,可以很輕鬆的適應(yīng)你的編程習(xí)慣。
爲(wèi)了便於開發(fā)者的從傳統(tǒng)的面向?qū)ο笳Z言過渡,JavaScript把對(duì)象作爲(wèi)語言的中心。幾乎所有JavaScript的數(shù)據(jù)要麼是一個(gè)對(duì)象要麼從對(duì)象中獲取。其實(shí)就連函數(shù)在JavaScript中也視爲(wèi)對(duì)象,這使得它們成爲(wèi)了JavaScript的一等公民。
使用和理解對(duì)象是整個(gè)JavaScript的關(guān)鍵。你可以在任何時(shí)候創(chuàng)建對(duì)象,在任何時(shí)候給對(duì)象添加,刪除屬性。JavaScript對(duì)象是如此的靈活,可以創(chuàng)造出其他語言不具有的獨(dú)特而有趣的模式。
本章致力於鑑別和使用兩種JavaScript基本數(shù)據(jù)類型:原始類型和引用類型。雖然兩種都是通過對(duì)象進(jìn)行訪問,但是理解它們行爲(wèi)之間的區(qū)別是非常重要的。
1.1 什麼是類型
JavaScript雖然沒有類的概念,但依然存在兩種類型:原始類型和引用類型。原始類型保存爲(wèi)簡單數(shù)據(jù)值。引用類型則保存爲(wèi)對(duì)象,其本質(zhì)是指向內(nèi)存位置的引用。
爲(wèi)了讓開發(fā)者都能夠把原始類型和引用類型按相同的方式處理,JavaScript花費(fèi)了很大努力來保證語言的一致性。
其他編程語言用棧存儲(chǔ)原始類型,用堆存儲(chǔ)引用類型,JavaScript則完全不同:它使用一個(gè)變量對(duì)象追蹤變量的生存期。原始值被直接保存在變量對(duì)象內(nèi),而引用值則作爲(wèi)一個(gè)指針保證在變量對(duì)象內(nèi),該指針指向?qū)嶋H對(duì)象在內(nèi)存在的存儲(chǔ)位置。雖然看上去原始值和引用值一樣,但是它們還是有區(qū)別的,本章稍後會(huì)介紹。
當(dāng)然,原始類型和引用類型還有其他區(qū)別。
1.2 原始類型
原始類型代表照原樣保存的一些簡單數(shù)據(jù),如true和25.JavaScript共有5種原始類型,如下:
boolean ? 布爾,值爲(wèi)true或false
number ? ?數(shù)字,值爲(wèi)任何整型或浮點(diǎn)數(shù)值
string ? ? ?字符串,值爲(wèi)由單引號(hào)或雙引號(hào)擴(kuò)出的單個(gè)字符或連續(xù)字符(JavaScript不區(qū)分字符類型)
null ? ? ? ?空類型,該原始值有且僅有一個(gè)值:null
undefined ?未定義,該原始類型也是有且僅有一個(gè)值:undefined(undefined會(huì)被賦給一個(gè)還沒有初始化的變量)
前三種(boolean,number,string)表現(xiàn)的行爲(wèi)類似,而後兩種(null和undefined)則有一點(diǎn)區(qū)別,本章後面將會(huì)討論。所有原始類型的值都有字面形式。字面形式是不被保存在變量種的值,如硬編碼的姓名或價(jià)格。下面是每種類型使用字面形式的例子。
//strings
var name ="Nicholas";
var selection="a";
//number
var count=5;
var cost=1.51;
//boolean
var found=true;
//null
var object=null;
//undefined
var flag=undefined;
var ref;//assigned undefined automatically
JavaScript和許多其他語言一樣,原始類型的變量直接保存原始值(而不是一個(gè)指向?qū)ο蟮闹羔槪?。?dāng)你將原始值賦值給一個(gè)變量時(shí),該值將被賦值到變量中。也就是說,如果你使一個(gè)變量等於另一個(gè)變量時(shí),每個(gè)變量有它自己的一份數(shù)據(jù)拷貝。例如,
var color1="red";
var color2=color1;
這裏,color1被賦值爲(wèi)"red"。變量color2被賦予color1的值,這樣變量color2中就保存了"red"。雖然color1和color2具有同樣的值,但是兩者毫無關(guān)聯(lián),改變color1的值是不影響color2,反之亦然。這是因爲(wèi)存在兩個(gè)不同的存儲(chǔ)地址,每個(gè)變量擁有一個(gè)。
因爲(wèi)每個(gè)含有原始值的變量使用自己的存儲(chǔ)空間,一個(gè)變量的改變不會(huì)影響到其他變量。例如
var color1="red";
var color2=color1;
console.log(color1);//red
console.log(color2);//red
color1="blue";
console.log(color1);//blue
console.log(color2);//red
這段代碼中,color1被改爲(wèi)“blue,而color2還保有原來的值"red”。
1.2.1 鑒別原始類型
鑒別原始類型的最佳方法是使用typeof操作符。它可以被用在字符串,數(shù)字,布爾和未定義類型。下面是typeof對(duì)不同原始類型的輸出。
console.log(typeof "nicholas"); //"string"
console.log(typeof 10);// number
console.log(typeof 5.1 ); //number
console.log(typeof true); //boolean
console.log(typeof undefined) undefined
正如我們所期望的那樣,對(duì)於字符串,typeof將返回"string",對(duì)於數(shù)字將返回'number'(無論整型還是浮點(diǎn)型),對(duì)於布爾類型將返回‘boolean’,對(duì)於未定義類型將返回'undefined'。對(duì)於空類型則有一些棘手。
下面那行代碼的運(yùn)行結(jié)果困擾了很多開發(fā)者
console.log(typeof null);//object
當(dāng)你運(yùn)行typeof null時(shí),結(jié)果是object。但是這是為什麼呢?(其實(shí)這已經(jīng)被設(shè)計(jì)和維護(hù)javascript的委員會(huì)TC39認(rèn)定是一個(gè)錯(cuò)誤。在邏輯上,你可以認(rèn)為null是一個(gè)空的對(duì)象指針,所以結(jié)果為‘object’,但這還是令人困惑)
判斷一個(gè)值是否為空類型嘴賤的方法是直接和null比較,如下。
console.log(value===null) //true or false
非強(qiáng)制轉(zhuǎn)換比較:
三等號(hào)在進(jìn)行比較時(shí)不會(huì)將變量強(qiáng)制轉(zhuǎn)換為另一種類型
1.3 引用類型
引用類型是指javascript中的對(duì)象,同時(shí)也是你在該語言中能找到的最接近類的東西。引用值時(shí)引用類型的實(shí)例,也是對(duì)象的同義詞(本章後面將用對(duì)象指代引用值)。對(duì)象是屬性的無序曆表。屬性包含鍵(始終是字符串)和值。如果一個(gè)屬性的值是函數(shù),它就被稱為方法。javascript中函數(shù)其實(shí)是引用值,除了函數(shù)可以運(yùn)行以外,一個(gè)包含數(shù)組的屬性和一個(gè)包含函數(shù)的屬性沒什麼區(qū)別。
當(dāng)然,在使用對(duì)象前,你必須先創(chuàng)建它們。
1.3.1 創(chuàng)建對(duì)象
有時(shí)候,把javascript對(duì)象想像成哈希表可以幫助你更好的理解對(duì)象的結(jié)構(gòu)。
javascript有好幾種方法可以創(chuàng)建對(duì)象,或者說實(shí)例化對(duì)象。第一種是使用new操作符合構(gòu)造函數(shù)。構(gòu)造函數(shù)就是通過new操作符來創(chuàng)建對(duì)象的函數(shù)--任何函數(shù)都可以是構(gòu)造函數(shù)。根據(jù)命名規(guī)範(fàn),javascript中的構(gòu)造函數(shù)用首字母大寫來跟非構(gòu)造函數(shù)進(jìn)行區(qū)分。例如下列代碼實(shí)例化一個(gè)通用對(duì)象,並將它的引用保存在object中。
var object = new Object();
因?yàn)橐妙愋筒辉谧兞恐兄苯颖4鎸?duì)象,所以本例中的object變量實(shí)際上並不包含對(duì)象的實(shí)例,而是一個(gè)指向內(nèi)存中實(shí)際對(duì)象所在位置的指針(或者說引用)。這是對(duì)象和原始值之間的一個(gè)基本差別,原始值是直接保存在變量中的。
當(dāng)你將一個(gè)對(duì)象賦值給變量時(shí),實(shí)際是賦值給這個(gè)變量一個(gè)指針。這意味著,將一個(gè)變量賦值給另一個(gè)變量時(shí),兩個(gè)變量各獲得了一份指針的拷貝,指向內(nèi)存中的同一個(gè)對(duì)象。例如,
var object1=new Object();
var object2=object1;
這段代碼先用new創(chuàng)建了一個(gè)對(duì)象並將其引用保存在object1中。然後將object1的值賦值給object2.兩個(gè)變量都指向第一行被創(chuàng)建的那個(gè)對(duì)象實(shí)例。
1.3.2 對(duì)象的引用解除
javascript語言有垃圾收集的功能,因此當(dāng)你使用引用類型時(shí)無需擔(dān)心內(nèi)存分配問題。但最好在不使用對(duì)象時(shí)將其引用解除,讓垃圾收集器對(duì)那塊內(nèi)存進(jìn)行釋放。解除引用的最佳手段是將對(duì)象變量重置為null。
var object1=new Object();
//do something
object1=null;//dereference
這裏,對(duì)象object1被創(chuàng)建然後使用,最後設(shè)置為null。當(dāng)內(nèi)存中的對(duì)象不再被引用後,垃圾收集器會(huì)把那塊內(nèi)存挪作它用(在那些使用幾百萬對(duì)象的巨型程序裡,對(duì)象引用解除尤其重要)
1.3.3 添加刪除屬性
在javascript中,對(duì)象另一個(gè)有趣的地方是你可以隨時(shí)添加和刪除其屬性。例如,
var object1=new Object();
var object2=object1;
object1.myCustomProperty="Awesome!";
console.log(object2.myCustomProperty);//"Awesome!"
這裏,object1上增加了myCustomProperty屬性,值為"Awesome!”。該屬性也可以被object2訪問到,因?yàn)閛bject1和object2指向同一個(gè)對(duì)象。
除了通用對(duì)象引用類型以外,javascript還有其他一些內(nèi)建類型任你使用。
1.4 內(nèi)建類型實(shí)例化
你已經(jīng)見過如何使用new Object()創(chuàng)建和使用通用對(duì)象。Object類型只是javascript提供的少量內(nèi)建引用類型之一。其他內(nèi)建類型各有它們的特殊用途,可在任何時(shí)候被實(shí)例化。
這些內(nèi)建類型如下:
Array ? 數(shù)組類型,以數(shù)字為索引的一組值的有序列表
Data ? ?日期和和時(shí)間類型
Error ? 運(yùn)行期錯(cuò)誤類型(還有一些更特別的錯(cuò)誤例子類型)
Function 函數(shù)類型
Object 通用對(duì)象類型
RegExp 正則表達(dá)式類型
可以用new來實(shí)例化每一個(gè)內(nèi)建引用類型,如下:
var items =new Array();
var now =new Date();
var error =new Error("Something bad happened");
var func =new Function("console.log('Hi')");
var object=new Object();
var re=new RegExp("\\d+");
1.4.1 字面形式
內(nèi)建引用類型有字面形式。字面形式允許你在不需要使用new操作符合構(gòu)造函數(shù)顯示創(chuàng)建對(duì)象的情況下生成引用值(你曾在本章前面見過原始類型的字面形式,包括字符串,數(shù)字,布爾,空類型和為定義)。
1.4.2 對(duì)象和數(shù)組字面形式
要用對(duì)象字面形式創(chuàng)建對(duì)象,可以在大括號(hào)內(nèi)定義一個(gè)新對(duì)象及其屬性。屬性的組成包括一個(gè)表示符或字符串,一個(gè)冒號(hào)以及一個(gè)值。多個(gè)屬性值之間用逗號(hào)分割。例如
var book ={
name:"The Principles of Object-Oriented JavaScript",
year:2014
};
屬性名字也可以用字符串表示,特別是當(dāng)你希望名字中包含空格或其他特殊字符時(shí)。
var book={
"name":"The Principles of Object-Oriented JavaScript",
"year":2014
};
本例等價(jià)於前一個(gè)例子,僅在語法上有區(qū)別,下面是另一個(gè)等價(jià)寫法。
var book=new Object();
book.name="The Principles of Object-Oriented JavaScript";
book.year=2014;
雖然3例的結(jié)果是一致的:一個(gè)具有兩個(gè)屬性的對(duì)象。寫法完全取決於你。
注意:雖然使用字面形式並沒有調(diào)用new Object(),但是javascript引擎背後做的工作和new Object()一樣,除了密友調(diào)用構(gòu)造函數(shù),其他引用 類型的字面形式也是如此。
定義數(shù)組的字面形式是在中括號(hào)內(nèi)使用逗號(hào)區(qū)分的人士數(shù)量的值。例如:
var colors=["red","blue","green"];
console.log(colors[0]);//''red"
這段代碼等價(jià)於
var colors=new Array("red","blue","green");
console.log(colors[0]);
1.4.3 函數(shù)字面形式
基本上都要用字面形式來定義函數(shù)??紤]到在可維護(hù)性,易讀性和調(diào)試上的巨大挑戰(zhàn),通常不會(huì)有人使用函數(shù)的構(gòu)造函數(shù),因此很少看到用字符串表示的代碼而不是實(shí)際的代碼。
使用字面形式創(chuàng)建函數(shù)更方便也更不容易出錯(cuò)。如下例:
function reflect(value){
return value;
}
//is the same
var reflect=new Function("value","return value;");
1.4.4正則表達(dá)式字面形式
javascript允許使用字面形式而不是RexExp構(gòu)造函數(shù)定義正則表達(dá)式。它們看上去類似Perl中的正則表達(dá)式;模式被包含在兩個(gè)“/”之間,第二個(gè)“/”後是由單字符表示的額外的選項(xiàng)。
var number =/\d+/g;
// is the same as
var numbers = new RegExp("\\d+","g");
使用字面形式比較方便的一個(gè)原因是你不需要擔(dān)心字符串中的轉(zhuǎn)億字符。如果使用RegExp構(gòu)造函數(shù),傳入模式的參數(shù)時(shí)一個(gè)字符串,你需要對(duì)任何反斜槓進(jìn)行轉(zhuǎn)義。在javascript中,除非需要通過一個(gè)或多個(gè)字符串動(dòng)態(tài)構(gòu)造函數(shù)表達(dá)式,否則都建議使用字面形式而不是構(gòu)造函數(shù)。
總之,除了函數(shù),對(duì)內(nèi)建類型沒有什麼正確或錯(cuò)誤的實(shí)例化方法。很多開發(fā)者喜歡字面形式,另一些則喜歡用構(gòu)造函數(shù),你可以選擇能令你更舒服的那種。
1.5 訪問屬性
屬性時(shí)對(duì)象中保存的名字和值的配對(duì)。點(diǎn)號(hào)時(shí)javascript中訪問屬性的最通用的做法(就跟許多面向?qū)ο蟮恼Z言一樣),不過也可以用中括號(hào)訪問javascript對(duì)象的屬性。
例如,下面的代碼使用點(diǎn)號(hào)。
var array=[];
array.push(12345);
也可以如下例用中括號(hào),方法的名字現(xiàn)在由中括號(hào)中的字符串表示。
var array=[];
array["push"](12345);
在需要?jiǎng)討B(tài)決定訪問那個(gè)屬性的時(shí)候,這個(gè)語法特別游泳。例如下例中的中括號(hào)允許你用變量而不是字符串字面形式來制定訪問的屬性。
var array=[];
var method="push";
array[method](12345);
在這段代碼中,變量method的值時(shí)“push”,因此在array上調(diào)用了push()方法。這種能力及其有用,你會(huì)在本書中隨處看到這種用法。記住一點(diǎn):除了語法不同,在性能或其他方面點(diǎn)號(hào)和中括號(hào)都大致相同,唯一的區(qū)別在於中括號(hào)允許你在屬性名字上使用特殊字符。開發(fā)者通常認(rèn)為點(diǎn)號(hào)更加容易讀,所以你更多的看到點(diǎn)號(hào)而不是中括號(hào)。
1.6 鑒別引用類型
函數(shù)是最容易鑒別的引用類型,因?yàn)閷?duì)眼熟使用typeof操作符時(shí),返回值是“function”。
function reflect(value){
return value;
}
console.log(typeof reflect);//function
對(duì)其他引用類型的鑒別則較為棘手,因?yàn)閷?duì)於非函數(shù)的引用類型,typeof返回“object”。在處理很多不同類型的時(shí)候幫不上什麼忙,為了更方便的鑒別引用類型,可以使用javascript的instanceof操作符。
instanceof 操作符以一個(gè)對(duì)象和一個(gè)構(gòu)造函數(shù)為參數(shù)。如果對(duì)象是構(gòu)造函數(shù)所制定的類型的一個(gè)實(shí)例,instanceof返回ture;否則返回false,如下例:
var items =[];
var object={};
function reflect(value){
return value;
}
console.log(items instanceof Array); //true
console.log(object instanceof Object);//true
console.log(reflect instanceof Function); //true
本例用instanceof和構(gòu)造函數(shù)測試了幾個(gè)值,它們真正的類型都正確鑒別出來(即使該構(gòu)造函數(shù)並沒有被用於創(chuàng)造該變量)。
instanceof操作符可鑒別繼承類型。這意味著所有對(duì)象都是object的實(shí)例,因?yàn)樗幸妙愋投祭^承自object。
1.7 鑒別數(shù)組
雖然,instanceof可以鑒別數(shù)組,但是有一個(gè)例外會(huì)影響網(wǎng)頁開發(fā)者:javascript的值可以在同一個(gè)網(wǎng)頁的不同框架之間傳來傳去。當(dāng)你試圖鑒別一個(gè)引用值的類型的時(shí)候,這就有有可能成為一個(gè)問題,因?yàn)槊恳粋€(gè)頁面擁有它自己的上下文-Object,Array以及其他內(nèi)建類型的版本。結(jié)果,當(dāng)你把一個(gè)數(shù)組從一個(gè)框架傳到另一個(gè)框架時(shí),instanceof就無法識(shí)別它,因?yàn)槟莻€(gè)數(shù)組時(shí)來自不同框架的array的實(shí)例。
為了解決這個(gè)問題,ECMAScript5引入了array.isArray()來明確鑒別一個(gè)值是否為array的實(shí)例,無論該值來自哪裏該方法對(duì)來自任何上下文的數(shù)組都返回true。如果你的環(huán)境兼容ECMAScript 5,Array。isArray()是鑒別數(shù)組的最佳辦法。
var items=[];
console.log(Array.isArray(items));//true
大多數(shù)環(huán)境都在瀏覽器和node中指出這個(gè)方法,ie8或更糟的版本不支持該方法
1.8 原始封裝類型
javascript中一個(gè)最讓人困惑的部分可能就是原始封裝類型。原始封裝類型共有三種(String,Number and Boolean) ?這些特殊引用類型的存在使得原始類型用起來和對(duì)象一樣方便。(如果你不得不用獨(dú)特的語法和或切換為基於過程的編成方式來獲取一個(gè)字符串,那就太讓人困惑了)。
當(dāng)獲取字符串,數(shù)字或布爾值,原始封裝類型將被自動(dòng)創(chuàng)建。例如,下面代碼第一行,一個(gè)原始字符串的值被賦給name,第二行代碼把name當(dāng)成一個(gè)對(duì)象,使用點(diǎn)號(hào)調(diào)用了charAt方法
var name ="Nicholas";
var firstChar=name.charAt(0);
console.log(firstChar);
這是在背後發(fā)生的事情如下:
//what the Javascript engine does
var name ="Nicholas";
var temp =new String(name);
var firstChar=temp.CharAt(0);
temp =null;
console.log(firstChar);
由於第二行把字符串當(dāng)成對(duì)象使用,javascript引擎創(chuàng)建了一個(gè)字符串實(shí)體讓charAt(0)可以工作。字符串對(duì)象的存在僅僅用於該語句並在隨後被銷毀(一個(gè)稱為自動(dòng)打包的過程)。為了測試這多一點(diǎn)。試著給字符串添加一個(gè)屬性看看它是不是對(duì)象。
var name="Nicholeas";
name.last="Zakas";
console.log(name.last); ?//undefined
這段代碼試圖給字符串name添加last屬性,代碼運(yùn)行時(shí)沒有錯(cuò)誤,但是屬性消失了,到底放生了什麼?你可以在任何時(shí)候給一個(gè)真的對(duì)象添加屬性,屬性會(huì)保留至你手動(dòng)刪除他們。原始封裝類型的屬性會(huì)消失時(shí)因?yàn)樘砑訉傩缘膶?duì)象立刻就被銷毀了。
下面是在javascript引擎中實(shí)際發(fā)生的事情。
//what the javascript engine does
var name="Nicholas";
var temp = new String(name);
temp.last="Zakas";
temp =null;
var temp = new String(name);
console.log(temp.last);
temp=null;
實(shí)際上是在一個(gè)立刻就被銷毀的臨時(shí)對(duì)象上而不是字符串上添加了新的屬性,之後當(dāng)你試圖訪問該屬性時(shí),另一個(gè)不同的臨時(shí)對(duì)象被創(chuàng)建,而新屬性是不存在的。雖然原始封裝類型會(huì)被自動(dòng)創(chuàng)建,在這些值上進(jìn)行instanceof檢查對(duì)應(yīng)類型的返回值都是false。
var name ="Nicholas";
var count =0;
var found =false;
console.log(name instanceof String ); //false
console.log(count instanceof ?Number) //false
console.log(found instanceof Boolean) //false
這是因爲(wèi)臨時(shí)對(duì)象僅在值被讀取時(shí)創(chuàng)建。instanceof操作符並沒有真的讀取任何東西,也沒有臨時(shí)對(duì)象的創(chuàng)建,於是它告訴我們這些值並不屬於原始封裝類型。你也可以手動(dòng)創(chuàng)建原始封裝類型,但是有某些副作用。
手動(dòng)創(chuàng)建原始封裝類型實(shí)際會(huì)創(chuàng)建出一個(gè)object,這意味著typeof無法鑑別出來你實(shí)際保存的數(shù)據(jù)的類型。
另外,使用String,Number和Boolean對(duì)象和使用原始值有一定區(qū)別。例如,下列代碼使用了Boolean對(duì)象,對(duì)象的值是false,但是console.log("Found")亦然會(huì)被執(zhí)行,這是因爲(wèi)inyige對(duì)象在條件判斷語句中總是被認(rèn)爲(wèi)是true,無論該對(duì)象的值是不是等於false。
var found=new Boolean(false);
if(found){
console.log("Found");//this excutes
}
手工創(chuàng)建的原始封裝類型在其他地方很容易讓人誤解,在大多數(shù)情況下都只會(huì)導(dǎo)致錯(cuò)誤,所以,除非有特殊情況,否則你應(yīng)該避免這麼做。
1.9 總結(jié)
javascript中雖然沒有類,但是有類型。每個(gè)變量或數(shù)據(jù)都有一個(gè)對(duì)應(yīng)的原始類型或引用類型。5種原始類型(字符串,數(shù)字,布爾,空類型和未定義)的值會(huì)被直接保存在變量對(duì)象中,除了空類型,都可以用typefo來鑑別,空類型必須直接跟null進(jìn)行比較才能鑑別。
引用類型是javascript中最接近類的東西,而對(duì)戲則是引用類型的實(shí)例。可以用new操作符或字面形式創(chuàng)建新對(duì)象。通??梢杂命c(diǎn)號(hào)訪問屬性和方法,也可以用中括號(hào),函數(shù)在javascript中也是對(duì)象,可以用typeof來鑑別它們。至於其他引用類型,你應(yīng)該用instanceof和一個(gè)構(gòu)造函數(shù)來鑑別。
爲(wèi)了讓原始類型看上去更像引用類型,javascript提供了3種原始封裝類型:String和Number 還有Bolean,javascript會(huì)在背後創(chuàng)建這些對(duì)象使你能夠像使用普通對(duì)象那樣使用原始值,但是這些臨時(shí)對(duì)象在使用它們的語句結(jié)束的時(shí)候立刻被銷毀了,雖然你可以自己創(chuàng)建原始封裝類型的實(shí)例,但是它們太容易讓人誤解了,所以最好別這麼幹。