国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

《javascript高級程序設(shè)計(jì)》筆記:值類型與引用類型

TerryCai / 792人閱讀

摘要:因此,出于性能的考慮,在拷貝的方式選擇上,應(yīng)該結(jié)合具體的業(yè)務(wù)環(huán)境來進(jìn)行選擇參考專題之深淺拷貝深入剖析的深復(fù)制

基本數(shù)據(jù)類型是按值訪問的,因?yàn)榭梢圆僮鞅4嬖谧兞恐械膶?shí)際的值;
引用類型的值是保存在內(nèi)存中的對象,在操作對象時(shí),實(shí)際上是在操作對象的引用而不是實(shí)際的對象;

值類型

如果一個(gè)變量存儲(chǔ)的是值的本身那么就是一個(gè)值類型number / string / Boolean / Null / Undefined —值類型的變量本身就是含有賦予給它的數(shù)值的,它的變量本身及保存的數(shù)據(jù)都存儲(chǔ)在棧的內(nèi)存塊當(dāng)中,當(dāng)聲明一個(gè)值類型時(shí),必須對它初始化(給變量賦值)才能使用

var num1 = 123,
    num2 = num1;
num1 = 456;
console.log(num2);// 123

將值類型復(fù)制給另外一個(gè)值時(shí)(num2=num1),也就是num2重新再棧上開辟了一塊空間,然后將num1中的內(nèi)容復(fù)制一份放在num2中,當(dāng)改變其中一個(gè)變量的值時(shí),不會(huì)影響另外一個(gè)變量的值

引用類型

如果一個(gè)變量存儲(chǔ)的是引用(地址),那么就是一個(gè)引用類型object—引用類型的值的存儲(chǔ)與值類型不同,它分別存儲(chǔ)在內(nèi)存的堆和棧中,棧中存放的是指向堆中內(nèi)容的地址,堆中存放的引用類型的地址(鍵值對)

var obj1 = {name: "xyc"};
var obj2 = obj1;
obj1.name = "lxy";
console.log(obj2.name); // "lxy"

obj2=obj1表示的是將棧上的地址復(fù)制一份給另一個(gè)對象,他們同時(shí)指向堆中的內(nèi)容,當(dāng)修改內(nèi)容時(shí),兩個(gè)對象中的值都會(huì)發(fā)生改變

一個(gè)面試題
var o = new Object();
function foo(obj) {
  obj.name = "xyc";
  obj = new Object();
    obj.name = "lxy";
}
foo(o);
console.log(o.name); // ???

圖解:
(1)新建對象var o = new Object();

(2)在foo的環(huán)境下執(zhí)行obj.name = "xyc"
由于是參數(shù)傳遞,在局部作用域內(nèi)相當(dāng)于執(zhí)行了obj = o

(3)在局部作用域內(nèi)新建對象,并賦值相同的屬性值

obj = new Object();
obj.name = "lxy";

(4)foo()執(zhí)行完畢,局部作用域出棧,obj聲明周期結(jié)束
此時(shí),新建的對象依然存在,等待下一次內(nèi)存自動(dòng)回收機(jī)制將堆中的無引用對象銷毀

4. 變量的深淺拷貝(重點(diǎn))

什么是深淺拷貝?在mac電腦中我們可以對某個(gè)文件夾創(chuàng)建替身或者復(fù)制粘貼某個(gè)文件/文件夾,這兩種方式都實(shí)現(xiàn)了對某個(gè)文件/文件夾的拷貝,但是,前者在文件中修改文件內(nèi)容時(shí),源文件也會(huì)修改,而后者的操作在修改文件內(nèi)容時(shí)不會(huì)對源文件有影響

上面的例子,“創(chuàng)建替身” ==> 淺拷貝,“復(fù)制粘貼” ==> 深拷貝

從內(nèi)存角度說明:淺拷貝只會(huì)在棧內(nèi)存中開辟空間存放指向源文件的變量,而深拷貝會(huì)在堆內(nèi)存也拷貝文件

深淺拷貝僅是針對于數(shù)組和對象而言,不嚴(yán)謹(jǐn)?shù)恼f法,基本類型的拷貝都屬于深拷貝

(1)淺拷貝(最為常見)

var obj1 = {name: "xyc"};
var obj2 = obj1;
obj1.name = "lxy";
console.log(obj2.name); // "lxy"

僅將棧內(nèi)存復(fù)制,堆內(nèi)存中的指向依然相同,obj2對象改變后,會(huì)影響obj1對象

(2)拷貝對象及對象下一層的屬性和方法

var shallowCopy = function(obj) {
  // 只拷貝對象
  if (typeof obj !== "object") return;
  // 根據(jù)obj的類型判斷是新建一個(gè)數(shù)組還是對象
  var newObj = obj instanceof Array ? [] : {};
  // 遍歷obj,并且判斷是obj的屬性才拷貝
  for (var key in obj) {
    if (obj.hasOwnProperty(key)) {
      newObj[key] = obj[key];
    }
  }
  return newObj;
}
var obj1 = {
  name: "xyc",
  features: {
    say: "hello",
    eat: "something"
  }
}
var obj2 = shallowCopy(obj1);
obj2.features.eat = "anything";
console.log(obj1.features.eat); // "anything"

console.log(obj1 === obj2); // false
console.log(obj1.features === obj2.features); // true

上面這個(gè)例子可以看出上述方式的復(fù)制在對象內(nèi)嵌套對象是不能夠?qū)崿F(xiàn)“類深拷貝”的,下面有一個(gè)進(jìn)階型的

(3)遞歸調(diào)用對象中嵌套的對象

var deepCopy = function(obj) {
  // 只拷貝對象
  if (typeof obj !== "object") return;
  // 根據(jù)obj的類型判斷是新建一個(gè)數(shù)組還是對象
  var newObj = obj instanceof Array ? [] : {};
  // 遍歷obj,并且判斷是obj的屬性才拷貝
  for (var key in obj) {
    if (obj.hasOwnProperty(key)) {
      // 當(dāng)obj中嵌套對象時(shí),再次調(diào)用該方法
      newObj[key] = typeof obj[key] !== "object" ? obj[key] : deepCopy(obj[key]);
    }
  }
  return newObj;
}

(4)一維數(shù)組技巧性的拷貝

通過slice()concat()來實(shí)現(xiàn)

var arr = ["old", 1, true, null, undefined];

var new_arr = arr.concat();
// var new_arr = arr.slice();

new_arr[0] = "new";

console.log(arr) // ["old", 1, true, null, undefined]
console.log(new_arr) // ["new", 1, true, null, undefined]

一如上面的對象嵌套,多維數(shù)組使用上面的方式拷貝不徹底

(5)粗暴的拷貝方式

通過JSON.parse( JSON.stringify() )實(shí)現(xiàn)

var arr = ["old", 1, true, ["old1", "old2"], {old: 1}]

var new_arr = JSON.parse( JSON.stringify(arr) );

console.log(new_arr === arr);// false
console.log(new_arr[3] === arr[3]);// false

但是這種方式無法實(shí)現(xiàn)函數(shù)的拷貝

var arr = [function(){
    console.log(a)
}, {
    b: function(){
        console.log(b)
    }
}]

var new_arr = JSON.parse(JSON.stringify(arr));

console.log(new_arr);// [null, object]

函數(shù)通過這個(gè)方式會(huì)被轉(zhuǎn)換成null

(6)補(bǔ)全深拷貝

var deepCopy = function(obj){
    var str, newobj = obj.constructor === Array ? [] : {};
    if(typeof obj !== "object"){
        return;
    } else if(window.JSON){
        str = JSON.stringify(obj), //系列化對象
        newobj = JSON.parse(str); //還原
    } else {
        for(var i in obj){
            newobj[i] = typeof obj[i] === "object" ? 
            cloneObj(obj[i]) : obj[i]; 
        }
    }
    return newobj;
};

徹底的深拷貝理論上是將對象的整個(gè)原型鏈拷貝(無論原型屬性是否為enumerable均應(yīng)拷貝),遍歷的次數(shù)越多,性能消耗越大。因此,出于性能的考慮,在拷貝的方式選擇上,應(yīng)該結(jié)合具體的業(yè)務(wù)環(huán)境來進(jìn)行選擇

參考:
JavaScript專題之深淺拷貝
深入剖析 JavaScript 的深復(fù)制

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

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

相關(guān)文章

  • javascript高級程序設(shè)計(jì)筆記:內(nèi)存執(zhí)行環(huán)境

    摘要:因此,所有在方法中定義的變量都是放在棧內(nèi)存中的當(dāng)我們在程序中創(chuàng)建一個(gè)對象時(shí),這個(gè)對象將被保存到運(yùn)行時(shí)數(shù)據(jù)區(qū)中,以便反復(fù)利用因?yàn)閷ο蟮膭?chuàng)建成本通常較大,這個(gè)運(yùn)行時(shí)數(shù)據(jù)區(qū)就是堆內(nèi)存。 上一篇:《javascript高級程序設(shè)計(jì)》筆記:繼承近幾篇博客都會(huì)圍繞著圖中的知識(shí)點(diǎn)展開 showImg(https://segmentfault.com/img/bVY0C4?w=1330&h=618);...

    fuyi501 評論0 收藏0
  • 《你不知道的javascript筆記_對象&原型

    摘要:上一篇你不知道的筆記寫在前面這是年第一篇博客,回顧去年年初列的學(xué)習(xí)清單,發(fā)現(xiàn)僅有部分完成了。當(dāng)然,這并不影響年是向上的一年在新的城市穩(wěn)定連續(xù)堅(jiān)持健身三個(gè)月早睡早起游戲時(shí)間大大縮減,學(xué)會(huì)生活。 上一篇:《你不知道的javascript》筆記_this 寫在前面 這是2019年第一篇博客,回顧去年年初列的學(xué)習(xí)清單,發(fā)現(xiàn)僅有部分完成了。當(dāng)然,這并不影響2018年是向上的一年:在新的城市穩(wěn)定、...

    seasonley 評論0 收藏0
  • JavaScript高級程序設(shè)計(jì)筆記:變量、作用域和內(nèi)存問題(四)

    摘要:局部變量只在函數(shù)執(zhí)行過程中存在。此時(shí),局部變量就沒有存在的必要了,因此可以釋放他們所占的內(nèi)存以供他們使用。引用計(jì)數(shù)的含義是跟蹤記錄每個(gè)值被引用的次數(shù)。這一做法適合于大多數(shù)全局變量和局部變量的屬性。 基本類型和引用類型的值 ECMAScript變量可能包含兩種不同數(shù)據(jù)類型的值:基本類型值和引用類型值。基本類型值指的是簡單的數(shù)據(jù)段,而引用類型的值指那些可能有多個(gè)值構(gòu)成的對象。 動(dòng)態(tài)的屬性 ...

    Zack 評論0 收藏0
  • JavaScript高級程序設(shè)計(jì)筆記:變量、作用域、內(nèi)存問題

    摘要:作用域鏈中的下一個(gè)變量對象來自包含外部環(huán)境,而再下一個(gè)變量對象則來自下一個(gè)包含環(huán)境。這樣,一直延續(xù)到全局執(zhí)行環(huán)境全局執(zhí)行環(huán)境的變量對象始終都是作用域鏈中的最后一個(gè)對象標(biāo)識(shí)符解析沿作用域鏈一級一級搜索標(biāo)識(shí)符。 一、寫在前面 最近研究了創(chuàng)建Android虛擬機(jī)、vscode結(jié)合weex開發(fā)Android APP、Vmware裝MAC虛擬機(jī)的事,看的內(nèi)容不夠多,接下來加油 二、變量、作用域和...

    U2FsdGVkX1x 評論0 收藏0
  • 讀書筆記(02) - 可維護(hù)性 - JavaScript高級程序設(shè)計(jì)

    摘要:解耦優(yōu)勢代碼復(fù)用,單元測試。常用比較誤區(qū)可同時(shí)判斷,可用來判斷對象屬性是否存在。使用作判斷無法進(jìn)行充分的類型檢查。文件中應(yīng)用常量參考文檔高級程序設(shè)計(jì)作者以樂之名本文原創(chuàng),有不當(dāng)?shù)牡胤綒g迎指出。 showImg(https://segmentfault.com/img/bVburXw?w=500&h=400); 編寫可維護(hù)性代碼 可維護(hù)的代碼遵循原則: 可理解性 (方便他人理解) 直觀...

    k00baa 評論0 收藏0

發(fā)表評論

0條評論

最新活動(dòng)
閱讀需要支付1元查看
<