成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

JavaScript的賦值、深拷貝和淺拷貝

godlong_X / 796人閱讀

摘要:內(nèi)存空間分為兩種,棧內(nèi)存與堆內(nèi)存棧是系統(tǒng)自動分配的內(nèi)存空間,由系統(tǒng)自動釋放,堆則是動態(tài)分配的內(nèi)存,大小不定不會自動釋放。

JavaScript的內(nèi)存空間

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

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

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

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

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

棧內(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)存中的對象,在JavaScript中我們不能直接操作對象的堆內(nèi)存空間。因為引用類型的值都是按引用訪問的,所以在操作對象時,實際上是操作對象的引用而不是實際的對象。引用可以理解為保存在棧內(nèi)存中的一個地址,該地址指向堆內(nèi)存中的一個實際對象

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

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

內(nèi)存中的棧區(qū)域存放變量(基本類型的變量包括變量聲明和值)以及指向堆區(qū)域存儲位置的指針(引用類型的變量包括變量聲明和指向內(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ū)域中

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

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

引用類型總結(jié)

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

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

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

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

變量a和變量b的引用不同,對象就不是同一個對象
var a = {name:"Jay"};
var b = {name:"Jay"};
a===b //false

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

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

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

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

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

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

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

一種比較簡單實現(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}}

需要注意的是,使用JSON.Stringify()序列化對象時會把對象內(nèi)的function和原型成員忽略掉,示例如下

var obj = {
    name: "Jay Chou",
    job: "artist",
    say:function(){
        alert(this.job);
    }
}
JSON.stringify(obj);
//"{"name":"Jay Chou","job":"artist"}"

通過遞歸淺拷貝函數(shù)實現(xiàn)深拷貝

function deepCopy(obj){
    if(!obj || typeof obj !== "object"){
        return ;
    }
    var dcObj = Array.isArray(obj) ? [] : {};
    for(var key in obj){
        if(obj.hasOwnProperty(key)){
            if(obj[key] && typeof obj[key] === "object"){
                dcObj[key] = Array.isArray(obj[key]) ? [] : {};
                dcObj[key] = deepCopy(obj[key]);
            }
            dcObj[key] = obj[key]
        }
    }
    return dcObj;
}

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

賦值:變量獲得原對象的引用,改變該引用指向的對象的值(基本類型引用類型)其實就是修改原對象的值

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

深拷貝:改變新對象基本類型引用類型的值,都不會影響原對象,兩者互相獨立,互不影響

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/103594.html

相關(guān)文章

  • 拷貝和淺拷貝區(qū)別

    摘要:深拷貝和淺拷貝的區(qū)別背景最近在用框架寫頁面,賦值給中的對象時會出現(xiàn)一個問題,賦值和被賦值對象之中任何一個有變化,另一個也會隨之變化。 深拷貝和淺拷貝的區(qū)別 背景:最近在用vue框架寫頁面,賦值給Vue.$data中的對象時會出現(xiàn)一個問題,賦值和被賦值對象之中任何一個有變化,另一個也會隨之變化。例如: var b = { foo: 123 }; var vm = new Vue(...

    suemi 評論0 收藏0
  • JavaScript拷貝

    摘要:實際上,是禁止這樣做的。傳值和傳址基本數(shù)據(jù)類型賦值基本數(shù)據(jù)類型的賦值是在內(nèi)存中新開辟一段棧內(nèi)存,然后再把再將值賦值到新的棧中。結(jié)果見輸出,可以看出來,無論是修改賦值得到的對象和淺拷貝得到的都會改變原始數(shù)據(jù)。 存儲問題:深拷貝和淺拷貝的主要區(qū)別:在內(nèi)存中的存儲類型(堆和棧)不同堆:動態(tài)分配的內(nèi)存,大小不定也不會自動釋放棧:自動分配的內(nèi)存,由系統(tǒng)自動釋放數(shù)據(jù)類型: 基本數(shù)據(jù)類型: jav...

    zhjx922 評論0 收藏0
  • JavaScript拷貝和淺拷貝

    摘要:深拷貝和淺拷貝問題的本質(zhì)還是不同數(shù)據(jù)類型的存儲方式差異,尤其是引用數(shù)據(jù)類型的特殊。 深拷貝和淺拷貝問題的本質(zhì)還是不同數(shù)據(jù)類型的存儲方式差異,尤其是引用數(shù)據(jù)類型的特殊。showImg(https://segmentfault.com/img/bVbb8XH?w=1058&h=409); 現(xiàn)分別對賦值、淺拷貝、深拷貝做深入研究: 1.賦值 原理:直接將對象指針直接賦值給另一個變量 代碼: ...

    TalkingData 評論0 收藏0
  • 一篇文章理解JS數(shù)據(jù)類型、拷貝和淺拷貝

    摘要:接下來我們進入正片數(shù)據(jù)類型六種基本數(shù)據(jù)類型布爾值,和一個表明值的特殊關(guān)鍵字。一種數(shù)據(jù)類型,它的實例是唯一且不可改變的。在中是沒有方法是可以改變布爾值和數(shù)字的。參考資料深拷貝淺拷貝 前言 筆者最近整理了一些前端技術(shù)文章,如果有興趣可以參考這里:muwoo blogs。接下來我們進入正片: js 數(shù)據(jù)類型 六種 基本數(shù)據(jù)類型: Boolean. 布爾值,true 和 false. nu...

    EddieChan 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<