1、可以感受到,JS 的變量及其松散,那么,正是 JS 變量松散 的本質(zhì),決定了:JS 變量名只是 一個在特定的時間用于保存特定值的一個名字 而已,也就是說,變量的值及其數(shù)據(jù)類型可以在腳本的生命周期內(nèi)改變 ,盡管這個功能看起來有趣、強大,但是 JS 變量實際上是比較復雜。
洪江管理區(qū)網(wǎng)站建設公司創(chuàng)新互聯(lián),洪江管理區(qū)網(wǎng)站設計制作,有大型網(wǎng)站制作公司豐富經(jīng)驗。已為洪江管理區(qū)上千余家提供企業(yè)網(wǎng)站建設服務。企業(yè)網(wǎng)站搭建\外貿(mào)營銷網(wǎng)站建設要多少錢,請找那個售后服務好的洪江管理區(qū)做網(wǎng)站的公司定做!
2、ECMAScirpt 變量有兩種不同的數(shù)據(jù)類型:基本類型 和 引用類型,另外還有其他的叫法,比如:原始類型和對象類型、擁有方法的類型和不能擁有方法的類型 等/0
3、將一個值賦值給變量時,解析器 必須確定這個值是基本類型值還是引用類型值
基本類型 指的是簡單的數(shù)據(jù)段,而 引用類型 指的是可能由多個值構成的對象
基本類型:undefined、null、string、number、boolean、symbo(ES6)
引用類型:Object、Array、RegExp、Date、Function
兩種類型的區(qū)別
存儲:
基本類型的值是存放在 棧區(qū) 的,即內(nèi)存中的棧內(nèi)存
假如有以下變量:
var name = 'jozo'; var city = 'guangzhou'; var age = 22;
那么他們的存儲結(jié)構如下:(棧區(qū)包括了變量的標識符和值)
引用類型的值是同時保存在 棧內(nèi)存和堆內(nèi)存 的
假如有以下對象:
var person1 = {name:'jozo'}; var person2 = {name:'xiaom'}; var person3 = {name:'xiaoq'};
那么他們的存儲結(jié)構如下:
訪問:
基本類型的值是 按值訪問 的,因為可以操作保存在變量中的實際的值。
引用類型的值是 按引用訪問 的,因為引用類型的值是保存在內(nèi)存中的對象,而與其他語言不同的是,JavaScript 不允許直接訪問內(nèi)存中的位置,即不可以直接操作對象的內(nèi)存空間,那么,在操作對象時,實際上是在操作對象的引用而不是實際的對象。
動態(tài)的屬性:
對于引用類型的值,很明顯,我們可以為其 添加、改變、刪除 屬性和方法:
var person = new Object(); person.name = "Ozzie"; console.log(person.name); //"Ozzie"
上述過程中,我們創(chuàng)建了一個對象并為其添加了一個屬性,如果對象不被銷毀或者這個屬性不被刪除,那么這個屬性將一直存在
但是,我們不可以給基本類型的值添加方法和屬性
var name = "Ozzie"; name.age = 19; consoe.log(name.age); //undefined
盡管這樣操作不會報錯,但是仍然會被默默地掛掉
比較:
基本類型的比較是 值的比較 :
例如:
var a = 1;
var b = true;
console.log(a == b); //true
引用類型的比較是 引用的比較 :
例如:
var person1 = {}; var person2 = {}; console.log(person1 == person2); //false
上文提到過,引用類型時按引用訪問的,換句話說就是比較兩個對象的堆內(nèi)存中的地址是否相同,很明顯,并不是同一個內(nèi)存位置:
復制變量值:
將一個基本類型的值復制給另一個變量,那么,會在新變量上創(chuàng)建一個新值,然后再把該值復制到為新變量分配的位置上:
例如:
var a = 10; var b = a; a++; console.log(a); // 11 console.log(b); // 10
a 與 b 是完全獨立的,該值只是 a 中的值的一個副本。
基本類型在賦值操作后,兩個變量是相互不受影響的:
那么,復制引用類型的值時,同樣也會將一份存儲在對象中的值復制到新變量的空間中,不同的是,這個值的副本實際上是一個 指針,指向的是存儲在堆中的對象。也就是說,復制結(jié)束后,這兩個變量將引用同一個對象。
例如:
var a = {}; // a保存了一個空對象的實例 var b = a; // a和b都指向了這個空對象 a.name = 'jozo'; console.log(a.name); // 'jozo' console.log(b.name); // 'jozo'
改變其中一個變量就會影響到另一個變量
傳遞參數(shù):
請記住,盡管在訪問變量時有著按值訪問和按引用訪問這兩種方式,但 ECMAScript 中所有的函數(shù)的參數(shù)都是按值傳遞的,即參數(shù)只能按值傳遞,也就是說,把函數(shù)外部的值復制給函數(shù)內(nèi)部的參數(shù),就類似于變量之間的值復制一樣
基本類型的值的傳遞如同基本類型的變量的復制,被傳遞的值會被賦值給一個局部變量(即命名參數(shù),用 ECMAScript 中的概念說,就是 arguments 對象中的一個元素),此處不再贅述…
但是向參數(shù)傳遞引用類型的值時,復制給局部變量的是 內(nèi)存中的地址,因此這個局部變量的變化會被反映在函數(shù)的外部。
例如:
function setName(obj){ obj.name = "Ozzie"; } var person = new Object(); setName(person); console.log(person.name); //"Ozzie"
我們可以看到,在函數(shù)內(nèi)部,obj 和 person 引用的是同一個對象,換句話說,即使這個變量是按值傳遞的,obj 也會按引用來訪問同一個對象,因為 person 指向的對象在堆內(nèi)存中只有一個,而且是全局對象。
很多人會 錯誤地認為:參數(shù)是按引用傳遞的,因為在局部作用域中修改的參數(shù)會在全局作用域中反映出來,OK,那么我們再看一個例子:
function setName(obj){ obj.name = "Ozzie"; obj = new Object(); obj.name = "Nicholas" } var person = new Object(); setName(person); console.log(person.name); //Ozzie
如果是按引用傳遞參數(shù)的,那么顯然 person 對象就會在函數(shù)內(nèi)部自動修改 name 屬性為 Nicholas,但結(jié)果仍然是 Ozzie,這說明,即使在函數(shù)內(nèi)部修改了參數(shù)的值,但原始的引用仍然保持不變,實際上,在函數(shù)內(nèi)部重寫 obj 時,這個變量的引用就是一個局部對象了,而這個局部對象在函數(shù)執(zhí)行完畢后立即被銷毀。
以上就是JS 基本類型與引用類型值的詳細內(nèi)容,更多請關注創(chuàng)新互聯(lián)其它相關文章!
標題名稱:javascript的基本類型和引用類型的區(qū)別
網(wǎng)站地址:http://muchs.cn/article44/gdsiee.html
成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供動態(tài)網(wǎng)站、定制網(wǎng)站、網(wǎng)站設計、App開發(fā)、手機網(wǎng)站建設、軟件開發(fā)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)