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

資訊專欄INFORMATION COLUMN

一篇文章理解JS數(shù)據(jù)類型、深拷貝和淺拷貝

EddieChan / 2787人閱讀

摘要:接下來我們進入正片數(shù)據(jù)類型六種基本數(shù)據(jù)類型布爾值,和一個表明值的特殊關(guān)鍵字。一種數(shù)據(jù)類型,它的實例是唯一且不可改變的。在中是沒有方法是可以改變布爾值和數(shù)字的。參考資料深拷貝淺拷貝

前言

筆者最近整理了一些前端技術(shù)文章,如果有興趣可以參考這里:muwoo blogs。接下來我們進入正片:

js 數(shù)據(jù)類型

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

Boolean. 布爾值,true 和 false.

null. 一個表明 null 值的特殊關(guān)鍵字。 JavaScript 是大小寫敏感的,因此 null 與 Null、NULL或其他變量完全不同。

undefined. 變量未定義時的屬性。

Number. 表示數(shù)字,例如: 42 或者 3.14159。

String. 表示字符串,例如:"Howdy"

Symbol ( 在 ECMAScript 6 中新添加的類型).。一種數(shù)據(jù)類型,它的實例是唯一且不可改變的。

以及 Object 對象引用數(shù)據(jù)類型

大多數(shù)情況下,我們可以通過typeof屬性來判斷。只不過有一些例外,比如:

var fn = new Function ("a", "b", "return a + b")

typeof fn // function

關(guān)于function屬不屬于js的數(shù)據(jù)類型,這里也有相關(guān)的討論JavaScript 里 Function 也算一種基本類型?

基本類型 和 引用數(shù)據(jù)類型 的相關(guān)區(qū)別 基本數(shù)據(jù)類型

我們來看一下 MDN 中對基本數(shù)據(jù)類型的一些定義:

除 Object 以外的所有類型都是不可變的(值本身無法被改變)。例如,與 C 語言不同,JavaScript 中字符串是不可變的(譯注:如,JavaScript 中對字符串的操作一定返回了一個新字符串,原始字符串并沒有被改變)。我們稱這些類型的值為“原始值”。
var a = "string"
a[0] = "a"
console.log(a)  // string

我們通常情況下都是對一個變量重新賦值,而不是改變基本數(shù)據(jù)類型的值。在 js 中是沒有方法是可以改變布爾值和數(shù)字的。倒是有很多操作字符串的方法,但是這些方法都是返回一個新的字符串,并沒有改變其原有的數(shù)據(jù)。比如:

獲取一個字符串的子串可通過選擇個別字母或者使用 String.substr().

兩個字符串的連接使用連接操作符 (+) 或者 String.concat().

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

引用類型(object)是存放在堆內(nèi)存中的,變量實際上是一個存放在棧內(nèi)存的指針,這個指針指向堆內(nèi)存中的地址。每個空間大小不一樣,要根據(jù)情況開進行特定的分配,例如。

var person1 = {name:"jozo"};
var person2 = {name:"xiaom"};
var person3 = {name:"xiaoq"};

引用類型的值是可變的:

person1["name"] = "muwoo"

console.log(person1) // {name: "muwoo"}
傳值與傳址

了解了基本數(shù)據(jù)類型與引用類型的區(qū)別之后,我們就應(yīng)該能明白傳值與傳址的區(qū)別了。
在我們進行賦值操作的時候,基本數(shù)據(jù)類型的賦值(=)是在內(nèi)存中新開辟一段棧內(nèi)存,然后再把再將值賦值到新的棧中。例如:

var a = 10;
var b = a;

a ++ ;
console.log(a); // 11
console.log(b); // 10

所以說,基本類型的賦值的兩個變量是兩個獨立相互不影響的變量。

但是引用類型的賦值是傳址。只是改變指針的指向,例如,也就是說引用類型的賦值是對象保存在棧中的地址的賦值,這樣的話兩個變量就指向同一個對象,因此兩者之間操作互相有影響。例如:

var a = {}; // a保存了一個空對象的實例
var b = a;  // a和b都指向了這個空對象

a.name = "jozo";
console.log(a.name); // "jozo"
console.log(b.name); // "jozo"

b.age = 22;
console.log(b.age);// 22
console.log(a.age);// 22

console.log(a == b);// true

淺拷貝

先來看一段代碼的執(zhí)行:

var obj = {a: 1, b: {c: 2}}
var obj1 = obj
var obj2 = shallowCopy(obj);
function shallowCopy(src) {
    var dst = {};
     for (var prop in src) {
         if (src.hasOwnProperty(prop)) {
             dst[prop] = src[prop];
          }
      }
     return dst;
}

var obj3 = Object.assign({}, obj)

obj.a = 2
obj.b.c = 3

console.log(obj) // {a: 2, b: {c: 3}}
console.log(obj1) // {a: 2, b: {c: 3}}
console.log(obj2) // {a: 1, b: {c: 3}}
console.log(obj3) // {a: 1, b: {c: 3}}

這段代碼可以說明賦值得到的對象 obj1 只是將指針改變,其引用的仍然是同一個對象,而淺拷貝得到的的 obj2 則是重新創(chuàng)建了新對象。但是,如果原對象obj中存在另一個對象,則不會對對象做另一次拷貝,而是只復(fù)制其變量對象的地址。這是因為淺拷貝只復(fù)制一層對象的屬性,并不包括對象里面的為引用類型的數(shù)據(jù)。
對于數(shù)組,更長見的淺拷貝方法便是slice(0)concat()
ES6 比較常見的淺拷貝方法便是 Object.assign

深拷貝

通過上面的這些說明,相信你對深拷貝大致了解了是怎樣一個東西了:深拷貝是對對象以及對象的所有子對象進行拷貝。那么如何實現(xiàn)這樣一個深拷貝呢?

1. JSON.parse(JSON.stringify(obj))

對于常規(guī)的對象,我們可以通過JSON.stringify來講對象轉(zhuǎn)成一個字符串,然后在用JSON.parse來為其分配另一個存儲地址,這樣可以解決內(nèi)存地址指向同一個的問題:

var obj = {a: {b: 1}}
var copy = JSON.parse(JSON.stringify(obj))

obj.a.b = 2
console.log(obj) // {a: {b: 2}}
console.log(copy) // {a: {b: 1}}

但是 JSON.parse()JSON.stringify也存在一個問題,JSON.parse() 和J SON.stringify()能正確處理的對象只有Number、String、Array等能夠被 json 表示的數(shù)據(jù)結(jié)構(gòu),因此函數(shù)這種不能被 json 表示的類型將不能被正確處理。

var target = {
    a: 1,
    b: 2,
    hello: function() { 
            console.log("Hello, world!");
    }
};
var copy = JSON.parse(JSON.stringify(target));
console.log(copy);   // {a: 1, b: 2}
console.log(JSON.stringify(target)); // "{"a":1,"b":2}"
2. 遍歷實現(xiàn)屬性復(fù)制

既然淺拷貝只能實現(xiàn)非object第一層屬性的復(fù)制,那么遇到object只需要通過遞歸實現(xiàn)淺拷貝其中內(nèi)部的屬性即可:

function extend (source) {
  var target
  if (typeof source === "object") {
    target = Array.isArray(source) ? [] : {}
    for (var key in source) {
      if (source.hasOwnProperty(key)) {
        if (typeof source[key] !== "object") {
          target[key] = source[key]
        } else {
          target[key] = extend(source[key])
        }
      }
    }
  } else {
    target = source
  }
  return target
}

var obj1 = {a: {b: 1}}
var cpObj1 = extend(obj1)
obj1.a.b = 2
console.log(cpObj1) // {a: {b: 1}}

var obj2 = [[1]]
var cpObj2 = extend(obj2) 
obj2[0][0] = 2
console.log(cpObj2) // [[1]]

我們再來看一下 Zepto 中深拷貝的代碼:

    // 內(nèi)部方法:用戶合并一個或多個對象到第一個對象
    // 參數(shù):
    // target 目標(biāo)對象  對象都合并到target里
    // source 合并對象
    // deep 是否執(zhí)行深度合并
    function extend(target, source, deep) {
        for (key in source)
            if (deep && (isPlainObject(source[key]) || isArray(source[key]))) {
                // source[key] 是對象,而 target[key] 不是對象, 則 target[key] = {} 初始化一下,否則遞歸會出錯的
                if (isPlainObject(source[key]) && !isPlainObject(target[key]))
                    target[key] = {}

                // source[key] 是數(shù)組,而 target[key] 不是數(shù)組,則 target[key] = [] 初始化一下,否則遞歸會出錯的
                if (isArray(source[key]) && !isArray(target[key]))
                    target[key] = []
                // 執(zhí)行遞歸
                extend(target[key], source[key], deep)
            }
            // 不滿足以上條件,說明 source[key] 是一般的值類型,直接賦值給 target 就是了
            else if (source[key] !== undefined) target[key] = source[key]
    }

內(nèi)部實現(xiàn)其實也是差不多。

參考資料

js 深拷貝 vs 淺拷貝

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

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

相關(guān)文章

  • 文章理解JS數(shù)據(jù)類型、拷貝和淺拷貝

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

    enda 評論0 收藏0
  • 文章徹底說清JS拷貝/淺拷貝

    摘要:一篇文章徹底說清的深拷貝淺拷貝這篇文章的受眾第一類業(yè)務(wù)需要急需知道如何深拷貝對象的開發(fā)者。這篇文章分享的目的更多還是希望用一篇文章整理清楚深淺拷貝的含義遞歸實現(xiàn)思路以及小伙伴們?nèi)绻褂昧诉@種黑科技一定要清楚這樣寫的優(yōu)缺點。 一篇文章徹底說清JS的深拷貝and淺拷貝 這篇文章的受眾 第一類,業(yè)務(wù)需要,急需知道如何深拷貝JS對象的開發(fā)者。 第二類,希望扎實JS基礎(chǔ),將來好去面試官前秀操作...

    J4ck_Chan 評論0 收藏0
  • 文章徹底說清JS拷貝/淺拷貝

    摘要:一篇文章徹底說清的深拷貝淺拷貝這篇文章的受眾第一類業(yè)務(wù)需要急需知道如何深拷貝對象的開發(fā)者。這篇文章分享的目的更多還是希望用一篇文章整理清楚深淺拷貝的含義遞歸實現(xiàn)思路以及小伙伴們?nèi)绻褂昧诉@種黑科技一定要清楚這樣寫的優(yōu)缺點。 一篇文章徹底說清JS的深拷貝and淺拷貝 這篇文章的受眾 第一類,業(yè)務(wù)需要,急需知道如何深拷貝JS對象的開發(fā)者。 第二類,希望扎實JS基礎(chǔ),將來好去面試官前秀操作...

    lakeside 評論0 收藏0
  • 文章徹底說清JS拷貝/淺拷貝

    摘要:一篇文章徹底說清的深拷貝淺拷貝這篇文章的受眾第一類業(yè)務(wù)需要急需知道如何深拷貝對象的開發(fā)者。這篇文章分享的目的更多還是希望用一篇文章整理清楚深淺拷貝的含義遞歸實現(xiàn)思路以及小伙伴們?nèi)绻褂昧诉@種黑科技一定要清楚這樣寫的優(yōu)缺點。 一篇文章徹底說清JS的深拷貝and淺拷貝 這篇文章的受眾 第一類,業(yè)務(wù)需要,急需知道如何深拷貝JS對象的開發(fā)者。 第二類,希望扎實JS基礎(chǔ),將來好去面試官前秀操作...

    big_cat 評論0 收藏0

發(fā)表評論

0條評論

EddieChan

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<