JavaScript中內(nèi)存空間、賦值和深淺拷貝的示例分析-創(chuàng)新互聯(lián)

這篇文章將為大家詳細(xì)講解有關(guān)JavaScript中內(nèi)存空間、賦值和深淺拷貝的示例分析,小編覺得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。

創(chuàng)新互聯(lián)公司長(zhǎng)期為1000多家客戶提供的網(wǎng)站建設(shè)服務(wù),團(tuán)隊(duì)從業(yè)經(jīng)驗(yàn)10年,關(guān)注不同地域、不同群體,并針對(duì)不同對(duì)象提供差異化的產(chǎn)品和服務(wù);打造開放共贏平臺(tái),與合作伙伴共同營(yíng)造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為桃源企業(yè)提供專業(yè)的成都做網(wǎng)站、成都網(wǎng)站建設(shè),桃源網(wǎng)站改版等技術(shù)服務(wù)。擁有十年豐富建站經(jīng)驗(yàn)和眾多成功案例,為您定制開發(fā)。

JavaScript的內(nèi)存空間

在JavaScript中,每一個(gè)數(shù)據(jù)都需要一個(gè)內(nèi)存空間。內(nèi)存空間分為兩種,棧內(nèi)存(stack)與堆內(nèi)存(heap)

棧是系統(tǒng)自動(dòng)分配的內(nèi)存空間,由系統(tǒng)自動(dòng)釋放,堆則是動(dòng)態(tài)分配的內(nèi)存,大小不定不會(huì)自動(dòng)釋放。

基礎(chǔ)數(shù)據(jù)類型

JavaScript中的基礎(chǔ)數(shù)據(jù)類型,這些值都有固定的大小,保存在棧內(nèi)存中,由系統(tǒng)自動(dòng)分配存儲(chǔ)空間在棧內(nèi)存空間的值,我們可以直接進(jìn)行操作,因此基礎(chǔ)數(shù)據(jù)類型都是按照值訪問

在棧內(nèi)存中的數(shù)據(jù)發(fā)生復(fù)制的行為時(shí),系統(tǒng)會(huì)自動(dòng)為新變量開辟一個(gè)新的內(nèi)存空間,當(dāng)復(fù)制執(zhí)行后,兩個(gè)內(nèi)存空間的值就互不影響,改變其中一個(gè)不會(huì)影響另一個(gè)

棧內(nèi)存空間數(shù)據(jù)復(fù)制示例
var a = `I am variable a`;
var b = a; 
console.log(b); //`I am variable a`
b = `I am variable b`;
console.log(a); //`I am variable a`
console.log(b); //`I am variable b`

引用數(shù)據(jù)類型

引用類型的值是保存在堆內(nèi)存中的對(duì)象,在JavaScript中我們不能直接操作對(duì)象的堆內(nèi)存空間。因?yàn)橐妙愋偷闹刀际前匆迷L問的,所以在操作對(duì)象時(shí),實(shí)際上是操作對(duì)象的引用而不是實(shí)際的對(duì)象。引用可以理解為保存在棧內(nèi)存中的一個(gè)地址,該地址指向堆內(nèi)存中的一個(gè)實(shí)際對(duì)象

引用類型值的復(fù)制,系統(tǒng)會(huì)為新的變量自動(dòng)分配一個(gè)新的棧內(nèi)存空間這個(gè)棧內(nèi)存空間保存著與被復(fù)制變量相同的指針,盡管他們?cè)跅?nèi)存中的內(nèi)存空間的位置互相獨(dú)立但是在堆內(nèi)存中訪問到的對(duì)象實(shí)際上是同一個(gè),因此,當(dāng)我們改變其中一個(gè)對(duì)象的值時(shí),實(shí)際上就是改變?cè)瓉淼膶?duì)象

棧內(nèi)存空間保存指針(地址),堆內(nèi)存空間保存實(shí)際的對(duì)象,我們通過變量訪問對(duì)象時(shí),實(shí)際上訪問的是對(duì)象的引用(地址)

內(nèi)存中的棧區(qū)域存放變量(基本類型的變量包括變量聲明和值)以及指向堆區(qū)域存儲(chǔ)位置的指針(引用類型的變量包括變量聲明和指向內(nèi)容的指針)

var a = {
  name : `I am object a`,
  type : 'object'
}

var b = a;
console.log(b);
// {name: "I am object a", type: "object"}

b.name = `I am object b`;

console.log(a);
// {name: "I am object b", type: "object"}

console.log(b);

// {name: "I am object b", type: "object"}

基本類型總結(jié)

基本數(shù)據(jù)類型:

包括:null、undefined、number、string、boolean、symbol(es6)

存放位置:內(nèi)存中的棧區(qū)域中

比較:值的比較,判斷是否相等,如果值相等,就相等。一般使用===進(jìn)行比較,因?yàn)?=會(huì)進(jìn)行類型的轉(zhuǎn)換

拷貝:賦值(通過(=)賦值操作符 賦值),賦值完成后,兩個(gè)變量之間就沒有任何關(guān)系了,改變其中一個(gè)變量的值對(duì)另一個(gè)沒有任何影響

引用類型總結(jié)

引用數(shù)據(jù)類型:

包括:數(shù)組、對(duì)象、函數(shù)

存放位置:內(nèi)存的棧區(qū)域中存放變量和指針,堆區(qū)域存儲(chǔ)實(shí)際的對(duì)象

比較:是引用的比較(就是地址的比較,變量在棧內(nèi)存中對(duì)應(yīng)的指針地址相等就指向同一個(gè)對(duì)象)判斷是否為同一個(gè)對(duì)象,示例如下

變量a和變量b的引用不同,對(duì)象就不是同一個(gè)對(duì)象
var a = {name:'Jay'};
var b = {name:'Jay'};
a===b //false

我們對(duì)JavaScript中引用類型進(jìn)行操作的時(shí)候,都是操作其對(duì)象的引用(保存在棧內(nèi)存中的指針)

賦值、深拷貝和淺拷貝 (Assignment, deep copy and shallow copy)

賦值:兩個(gè)變量的值(指針)都指向同一個(gè)對(duì)象,改變其中一個(gè),另一個(gè)也會(huì)受到影響

所謂拷貝就是復(fù)制,通過復(fù)制原對(duì)象生成一個(gè)新的對(duì)象

淺拷貝:重新在堆內(nèi)存中開辟一個(gè)空間,拷貝后新對(duì)象獲得一個(gè)獨(dú)立的基本數(shù)據(jù)類型數(shù)據(jù),和原對(duì)象共用一個(gè)原對(duì)象內(nèi)的引用類型數(shù)據(jù),改變基本類型數(shù)據(jù),兩個(gè)對(duì)象互不影響,改變其中一個(gè)對(duì)象內(nèi)的引用類型數(shù)據(jù),另一個(gè)對(duì)象會(huì)受到影響

var obj = {
  name: 'Jay Chou',
  age: 32,
  song:{
    name:'發(fā)如雪',
    year:2007
  }
}
var obj1 = obj;
function shallowCopy(obj){
  var scObj = {};
  for(var prop in obj){
    if(obj.hasOwnProperty(prop)){
      scObj[prop] = obj[prop]
    }
  }
  return scObj;
}
var obj2 = shallowCopy(obj);
console.log(obj === obj1,'obj === obj1','賦值');
console.log(obj === obj2,'obj === obj2','淺拷貝');
// true "obj === obj1" "賦值"
// false "obj === obj2" "淺拷貝"
console.log(obj.song === obj2.song);
//true
obj2.song.name='雙截棍';
obj2.name='Jay';
console.log(obj)
// {name: "Jay Chou", age: 32, song: {name:'雙截棍',year:2007}}
console.log(obj1);
// {name: "Jay Chou", age: 32, song: {name:'雙截棍',year:2007}}
console.log(obj2);
{name: "Jay", age: 32, song: {name:'雙截棍',year:2007}}
console.log(obj===obj1)
//true
console.log(obj===obj2)
//false

深拷貝:不論是對(duì)象內(nèi)的基本類型還是引用類型都被完全拷貝,拷貝后兩個(gè)對(duì)象互不影響

一種比較簡(jiǎn)單實(shí)現(xiàn)方法是使用var dcObj = JSON.parse(JSON.stringify(obj))

var obj = {
  name: 'Jay Chou',
  age: 32,
  song:{
    name:'發(fā)如雪',
    year:2007
  }
}

var dcObj=JSON.parse(JSON.stringify(obj));

console.log(dcObj);
// {name: "Jay Chou", age: 32, song: {name:'發(fā)如雪',year:2007}}
console.log(dcObj.song === obj.song);
//false
dcObj.name='Jay';
dcObj.song.name='雙截棍';
console.log(obj);
// {name: "Jay Chou", age: 32, song: {name:'發(fā)如雪',year:2007}}
console.log(dcObj);
//{name: "Jay", age: 32, song: {name:'雙截棍',year:2007}}

比較:賦值、深拷貝、淺拷貝

賦值:新對(duì)象仍然指向原對(duì)象,改變新對(duì)象的基本類型和引用類型的值都會(huì)使原對(duì)象對(duì)應(yīng)的值一同改變

淺拷貝:改變新對(duì)象基本類型的值不會(huì)使原對(duì)象對(duì)應(yīng)的值一起改變,但是改變新對(duì)象引用類型的值會(huì)使原對(duì)象對(duì)應(yīng)的值一同改變

深拷貝:改變新對(duì)象基本類型和引用類型的值,都不會(huì)影響原對(duì)象,兩者互相獨(dú)立,互不影響

關(guān)于“JavaScript中內(nèi)存空間、賦值和深淺拷貝的示例分析”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,使各位可以學(xué)到更多知識(shí),如果覺得文章不錯(cuò),請(qǐng)把它分享出去讓更多的人看到。

分享文章:JavaScript中內(nèi)存空間、賦值和深淺拷貝的示例分析-創(chuàng)新互聯(lián)
轉(zhuǎn)載源于:http://muchs.cn/article38/ceohsp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供商城網(wǎng)站App設(shè)計(jì)、搜索引擎優(yōu)化網(wǎng)站維護(hù)、微信小程序、ChatGPT

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

外貿(mào)網(wǎng)站制作