亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

javascript中基本類(lèi)型和引用類(lèi)型的區(qū)別分析

 更新時(shí)間:2015年05月12日 09:24:36   投稿:hebedich  
大多數(shù)人系統(tǒng)學(xué)習(xí)過(guò)的程序設(shè)計(jì)語(yǔ)言,在這些語(yǔ)言的學(xué)習(xí)過(guò)程中最早學(xué)到的幾個(gè)要點(diǎn)之一就是值類(lèi)型和引用類(lèi)型的區(qū)別。下面我們來(lái)看一下在 JavaScript 中基本數(shù)據(jù)類(lèi)型(Primitive Types)和引用類(lèi)型(Reference Types)的區(qū)別。

基本類(lèi)型和引用類(lèi)型

ECMAScript包含兩個(gè)不同類(lèi)型的值:基本類(lèi)型值和引用類(lèi)型值?;绢?lèi)型值指的是簡(jiǎn)單的數(shù)據(jù)段;引用類(lèi)型值指由多個(gè)值構(gòu)成的對(duì)象。當(dāng)我們把變量賦值給一個(gè)變量時(shí),解析器首先要做的就是確認(rèn)這個(gè)值是基本類(lèi)型值還是引用類(lèi)型值。

常見(jiàn)的五種基本數(shù)據(jù)類(lèi)型是:

Undifined、Null、Boolean、Number和String。這五種基本數(shù)據(jù)類(lèi)型可以直接操作保存在變量中的實(shí)際值。

看下面例子:

var a = 10;
var b = a;
   b = 20;
console.log(a); // 10
    
var bl = true;
var bl1 = bl;
   bl1 = false;
console.log(bl); // true

上面,b獲取值是a值的一份拷貝,雖然,兩個(gè)變量的值是相等,但是兩個(gè)變量保存兩不同的基本數(shù)據(jù)類(lèi)型值。b只是保存了a復(fù)制的一個(gè)副本。所以,當(dāng)b的值改變時(shí),a的值依然是10;
下面,兩個(gè)Boolean變量bl和bl1同樣是基本數(shù)據(jù)類(lèi)型,同樣保存兩個(gè)不同的基本數(shù)據(jù)據(jù)類(lèi)型值,bl1保存bl復(fù)制的一個(gè)副本。

下圖演示了這種基本數(shù)據(jù)類(lèi)型賦值的過(guò)程:

下面看一下引用類(lèi)型數(shù)據(jù):

javascript引用數(shù)據(jù)類(lèi)型是保存在堆內(nèi)存中的對(duì)象,與其它語(yǔ)言不同的是,你不可以直接訪問(wèn)堆內(nèi)存空間中的位置和操作堆內(nèi)存空間。只能通過(guò)操作對(duì)象的在棧內(nèi)存中的引用地址。所以引用類(lèi)型的數(shù)據(jù),在棧內(nèi)存中保存的實(shí)際上是對(duì)象在堆內(nèi)存中的引用地址。通過(guò)這個(gè)引用地址可以快速查找到保存在堆內(nèi)存中的對(duì)象。

看下下面的例子:

var obj1 = new Object();
var obj2 = obj1;
obj2.name = "我有名字了";
console.log(obj1.name); // 我有名字了

由上面例子,我們聲明了一個(gè)引用數(shù)據(jù)類(lèi)型變量obj1,并把它賦值給了另外一個(gè)引用數(shù)據(jù)類(lèi)型變量obj2。當(dāng)我們obj2添加了一個(gè)name屬性并賦值"我有名字了"。obj1同樣擁有了和obj2一樣的name屬性。說(shuō)明這兩個(gè)引用數(shù)據(jù)類(lèi)型變量指向同一個(gè)堆內(nèi)存對(duì)象。obj1賦值給obj2,實(shí)際只是把這個(gè)堆內(nèi)存對(duì)象在棧內(nèi)存的引用地址復(fù)制了一份給了obj2,但它們本質(zhì)上共同指向了同一個(gè)堆內(nèi)存對(duì)象。

下面我們來(lái)演示這個(gè)引用數(shù)據(jù)類(lèi)型賦值過(guò)程:

自然,給obj2添加name屬性,實(shí)際上是給堆內(nèi)存中的對(duì)象添加了name屬性,obj2和obj1在棧內(nèi)存中保存的只是堆內(nèi)存對(duì)象的引用地址,雖然也是拷貝了一份,但指向的對(duì)象卻是同一個(gè)。故而改變obj2引起了obj1的改變。

 一般而言,基本數(shù)據(jù)類(lèi)型是有固定數(shù)目的字節(jié)組成,這些字節(jié)可以在解析器的較底層進(jìn)行操作比如Number和Boolean;而引用數(shù)據(jù)類(lèi)型,可以包含任意數(shù)目的屬性和元素,因此它們無(wú)法像基本數(shù)據(jù)類(lèi)型那樣很容易的操作。由于,引用數(shù)據(jù)類(lèi)型的值是會(huì)發(fā)生變化的,所以通過(guò)跟基本數(shù)據(jù)類(lèi)型一樣的值傳遞方式,也就沒(méi)什么意義了,因?yàn)闀?huì)牽涉到大量的內(nèi)存的復(fù)制和比較,效率太低。所以引用數(shù)據(jù)類(lèi)型是通過(guò)引用傳遞方式,實(shí)際傳遞的只是對(duì)象的一個(gè)地址。比如Array和Function因?yàn)樗鼈兌际翘厥獾膶?duì)象所以它都是引用類(lèi)型。另外,引用類(lèi)型是可以添加屬性,基本類(lèi)型雖然也可以添加屬性,也不會(huì)報(bào)錯(cuò),經(jīng)測(cè)試添加完之后卻是無(wú)法訪問(wèn)的。

看下面代碼:

var a = 12;
 a.name = "myname";
console.log(a.name); // undefined

 String一個(gè)特殊的基本數(shù)據(jù)類(lèi)型

在很多語(yǔ)言中,String是以對(duì)象的形式表示的,但在ECMAScript里沒(méi)有沿用這種傳統(tǒng),String是當(dāng)作一種基本數(shù)據(jù)類(lèi)型,但它是一個(gè)比較特殊的基本類(lèi)型。

看上去好像String應(yīng)該做為一個(gè)引用類(lèi)型,可實(shí)際上它不是,因?yàn)樗皇菍?duì)象。那么看起來(lái)它應(yīng)該是基本數(shù)據(jù)類(lèi)型,應(yīng)該是通值傳遞的方式來(lái)操作。

看下面例子:

var stra = "這是一個(gè)字符串";
var strb = stra;
   stra = "這是另外一個(gè)字符串";
console.log(strb); // 這是一個(gè)字符串

 上面例子我們看到,仿佛stra通過(guò)值傳遞的方式復(fù)制了一份給了strb。當(dāng)stra改變的時(shí)候,strb并沒(méi)有改變,似乎我們已經(jīng)可以下結(jié)論,String就是個(gè)基本數(shù)據(jù)類(lèi)型。

可是,因?yàn)镾tring是可以任意長(zhǎng)度的,通過(guò)值傳遞,一個(gè)一個(gè)的復(fù)制字節(jié)顯示效率依然很低,看起來(lái)String也可以當(dāng)作引用類(lèi)型。

看下面例子:

var a = "myobject";
  a.name = "myname";
console.log(a.name); // undefined

顯示String無(wú)法當(dāng)作一個(gè)對(duì)象來(lái)處理。實(shí)際上,javascript里的String是不可以改變的,javascript也沒(méi)有提供任何一個(gè)改變字符串的方法和語(yǔ)法。

var a = "myobject";
  a = a.substring(3,5)
  console.log(a); // bj

記住這樣做,就沒(méi)有改變String字符串"myobject",只a引用了另一個(gè)字符串"bj","myobject"被回收了。

所以可以這樣講,String實(shí)際上并不符合上面兩種數(shù)據(jù)類(lèi)型分類(lèi)。它是具有兩方面屬性介于兩都之間的一種特殊類(lèi)型。

以上所述就是本文的全部?jī)?nèi)容了,希望大家能夠喜歡。

相關(guān)文章

最新評(píng)論