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

資訊專欄INFORMATION COLUMN

ES6時代,你真的會克隆對象嗎(二)

BoYang / 3342人閱讀

摘要:多個窗口意味著多個全局環(huán)境,不同的全局環(huán)境擁有不同的全局對象,從而擁有不同的內(nèi)置類型構(gòu)造函數(shù)。比如,表達式會返回,因為屬性得到的僅僅是構(gòu)造函數(shù),而且是可以被手動更改的,只是返回的構(gòu)造函數(shù)的名字,它并不返回類名。

原文:ES6時代,你真的會克隆對象嗎(二)

上一篇,我們從Symbol和是否可枚舉以及屬性描述符的角度分析了ES6下怎么淺拷貝一個對象,發(fā)表在掘金和segmentfault上(其他地方也能看到這篇文章,雖然并沒有人問過我的意見,即便我是同意的,但是連一個“轉(zhuǎn)”字,一個原文鏈接都不給,這就很讓人傷心了),從評論看,部分人覺著看不懂,今天,我們用更簡單的方式來聊聊ES6下深拷貝的問題

寫在前面

深拷貝的話題好像從來沒有停止過討論,JavaScript并沒有一個可以實現(xiàn)深拷貝的方法,我們常見的實現(xiàn)方式是遞歸和JSON.parse(JSON.stringify())(聽說底層還是用了遞歸),然而一般庫函數(shù)也只能處理常見的需求(不常見的需求真的存在嗎?真的需要用深拷貝嗎?真的不承認(rèn)是你代碼的問題嗎?)。今天,我就仔細(xì)、認(rèn)真,細(xì)致(也不是很細(xì)致),負(fù)責(zé)(也不敢太保證)的態(tài)度來研究一下怎么實現(xiàn)一個深拷貝吧,雖然一度放棄,事實也的確是放棄了,但不把這么多天的付出寫出來怎么對得起那個在這個寒冷的冬天忍住瑟瑟發(fā)抖的在鍵盤上敲擊的我...

常見深拷貝 JSON系列化

JSON.parse(JSON.stringify())的確是一種很簡單易用的方式呢,可惜的是,JSON是一個很有原則的男人,他可不會對你言聽計從。在遇到不安全的JSON值會自動將其忽略,在數(shù)組中則會返回null(以保證單元位置不變)。

不安全的 JSON 值: undefined 、 function 、 symbol (ES6+)和包含循環(huán)引用(對象之間相互引用,形成一個無限循環(huán))的 對象 都不符合 JSON 結(jié)構(gòu)標(biāo)準(zhǔn),支持 JSON 的語言無法處理它們
遞歸

上一篇講淺拷貝的時候,我們在開始引入了一個淺拷貝的例子,現(xiàn)在我們把它改成一件簡單的深拷貝。

function deepCopy (obj) {
  if (typeof obj !== "object") {
    return
  }
  var newObj = obj instanceof Array ? [] : {}
  for (var key in obj) {
    if (obj.hasOwnProperty(key)) {
      newObj[key] = typeof obj[key] === "object" ? deepCopy(obj[key]) : obj[key]
    }
  }
  return newObj
}

好像也還不錯,簡單易懂還能用,一般的場景的確是一種不錯的方法呢,但是,今天我們來看看不一般的場景。

我們先來挑挑毛?。?/p>

function類型沒有處理(大概,或許,應(yīng)該是真的沒必要吧,下面我也并不打算討論這貨,有興趣的去看看call、applybind

循環(huán)引用

類型判斷用typeofinstanceof靠譜嗎?(特別注意typeof null的坑)

數(shù)組?[]:{},這么簡單?不存在的

循環(huán)引用

上面多處說到了循環(huán)引用的問題,我們先來看看什么是循環(huán)引用:

var a = {}
a.b = a

是的,就是這么一個反人類的存在,但是卻是我們不能忽略的一個大問題。我們是應(yīng)該返回空呢、undefined呢,還是它的引用,還是什么呢?好像沒有標(biāo)準(zhǔn)答案呢,嗯,那就Follow Your Heart吧!

類型判斷

思考一下:

typeof null  // "object"
null instanceof Object  // false

進行類型判斷是無可避免的,然而我們似乎并沒有什么完美的方式得到我們需要的類型,我們先來看看幾種常用的方式:

typeof: 返回一個表達式的數(shù)據(jù)類型的字符串,返回結(jié)果為js基本的數(shù)據(jù)類型,包括number,boolean,string,object,undefined,function,symbol

instanceof: 判斷一個對象是否為某一數(shù)據(jù)類型,或一個變量是否為一個對象的實例;返回boolean類型。內(nèi)建類型只有通過構(gòu)造器才能用instanceof

constructor: 是每一個實例對象都擁有的屬性,而這個屬性也相當(dāng)于是一個指針,它指向于創(chuàng)建當(dāng)前對象的對象

Object.prototype.toString.call(obj).slice(8,-1): 返回的是類名

typeof的問題就很明顯了:

typeof null  // "object"
typeof function () {}  // "function"
typeof []  // "object"

instanceof考慮一下多全局對象(多個frame或多個window之間的交互),在瀏覽器中,我們的腳本可能需要在多個窗口之間進行交互。多個窗口意味著多個全局環(huán)境,不同的全局環(huán)境擁有不同的全局對象,從而擁有不同的內(nèi)置類型構(gòu)造函數(shù)。這可能會引發(fā)一些問題。比如,表達式 [] instanceof window.frames[0].Array 會返回false,因為 Array.prototype !== window.frames[0].Array.prototype

constructor屬性得到的僅僅是構(gòu)造函數(shù),而且是可以被手動更改的,constructor.name只是返回的構(gòu)造函數(shù)的名字,它并不返回類名。

Object.prototype.toString.call算是比較公認(rèn)靠譜的方法了吧,然而,它同樣有可能被人為仿造,鴨子類型嘛,但它還是比較安全的方式。

鴨子類型: "如果它走起路來像鴨子,叫起來也是鴨子,那么它就是鴨子"。動態(tài)類型的語言傾向于你讓它做什么它就是什么
類型分析

討論鋪墊的內(nèi)容應(yīng)該夠細(xì)了吧,接下來我們看看js的復(fù)雜數(shù)據(jù)類型到底有多復(fù)雜。

我們常見的有:

基本包裝類型(Boolean、String、Number)、function、Array、Date

你常見,但你不一定想的起的:

RegExp,Arguments,Error、NodeList

你不一定常見,你也不一定知道的:

Blob、File、FileList、ImageData

ES6:

Map、Set、WeakMap、WeakSet、ArrayBuffer對象、TypedArray視圖和DataView視圖、Float32Array、Float64Array、Int8Array...

或許列舉的少了不少,但是已經(jīng)夠讓人擔(dān)憂深克隆的復(fù)雜程度了,一一實現(xiàn)他們不是一件簡單的事情,甚至是一件完全沒有必要的事情(當(dāng)然可以讓你了解更多),推薦幾個很優(yōu)秀的方案供參考:

lodash克隆,lodash花了大量的代碼來實現(xiàn) ES6 引入的大量新的標(biāo)準(zhǔn)對象。更厲害的是,lodash 針對存在環(huán)的對象的處理也是非常出色的

jQuery克隆無法正確深復(fù)制 JSON 對象以外的對象

結(jié)構(gòu)化克隆算法

寫在最后

克隆的部分就寫的差不多了,本來想寫點Map、Set的內(nèi)容的,無賴,并沒有找到合適的地方,MDN、阮一峰的ECMAScript 6 入門都介紹的挺好的。

好吧,就這樣吧,前端界的小學(xué)生,不足之處,還請指正

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

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

相關(guān)文章

  • ES6時代,真的克隆對象

    摘要:原文你真的會克隆對象嗎開始之前在開始聊克隆之前,我們還是先來看看數(shù)據(jù)類型。值通過函數(shù)生成,是獨一無二的。同時,中規(guī)定了對象的屬性名有兩種類型,一種是字符串,另一種就是類型。返回一個數(shù)組,包含對象自身的所有屬性的鍵名。 原文:你真的會克隆對象嗎 開始之前 在開始聊克隆之前,我們還是先來看看js數(shù)據(jù)類型。js的數(shù)據(jù)類型分為基本數(shù)據(jù)類型和復(fù)雜數(shù)據(jù)類型。 基本數(shù)據(jù)類型:Number、Bool...

    xiaokai 評論0 收藏0
  • 白話es6系列真的聲明變量

    摘要:新增了二個聲明變量的關(guān)鍵字,和,再加上之前的,這樣聲明變量就有三個關(guān)鍵字了,大有三國鼎立之勢。當(dāng)?shù)闹禐闀r,該變量不會被聲明并初始化。如果上面的那個循環(huán)中用聲明變量,那么循環(huán)完了,變量也就隨時銷毀,不能再被訪問。 ES6新增了二個聲明變量的關(guān)鍵字,let和const,再加上ES6之前的var,這樣聲明變量就有三個關(guān)鍵字了,大有三國鼎立之勢。那到底用哪個來聲明變量呢? var 首先,得說說...

    maybe_009 評論0 收藏0
  • 真的懂switch?聊聊switch語句中的塊級作用域

    摘要:最近在代碼中不小心不規(guī)范的,在里面定義了塊級變量,導(dǎo)致頁面在某些瀏覽器中出錯,本文討論以下語句中的塊級作用域。而與無關(guān)每一個并不會構(gòu)成一個獨立的塊級作用域。 ??最近在代碼中不小心不規(guī)范的,在switch里面定義了塊級變量,導(dǎo)致頁面在某些瀏覽器中出錯,本文討論以下switch語句中的塊級作用域。 switch語句中的塊級作用域 switch語句中的塊級作用域可能存在的問題 規(guī)范和檢...

    zone 評論0 收藏0
  • 真的懂switch?聊聊switch語句中的塊級作用域

    摘要:最近在代碼中不小心不規(guī)范的,在里面定義了塊級變量,導(dǎo)致頁面在某些瀏覽器中出錯,本文討論以下語句中的塊級作用域。而與無關(guān)每一個并不會構(gòu)成一個獨立的塊級作用域。 ??最近在代碼中不小心不規(guī)范的,在switch里面定義了塊級變量,導(dǎo)致頁面在某些瀏覽器中出錯,本文討論以下switch語句中的塊級作用域。 switch語句中的塊級作用域 switch語句中的塊級作用域可能存在的問題 規(guī)范和檢...

    pkwenda 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<