ES6時代,你真的會轉殖物件嗎?

2021-09-14 04:02:13 字數 3281 閱讀 5810

原文:你真的會轉殖物件嗎

在開始聊轉殖之前,我們還是先來看看js資料型別。js的資料型別分為基本資料型別複雜資料型別

轉殖:基本資料 => 複製這個變數;複雜資料 => 拷貝引用(網上的介紹很多,不深入了)

對於物件的轉殖,應該大多數人都能實現出來,可能深、淺拷貝都能想出好幾種方式,我們先來聊聊淺拷貝。

乙個常見的淺拷貝一般是下面這樣:

function shallowcopy (obj) 

var newobj = obj instanceof array ? : {}

for (var key in obj)

} return newobj

}

或者更嚴謹一點的實現陣列的判斷:

object.prototype.tostring.call(arr) === '[object array]'
好像是沒什麼問題呢,畢竟經過了好多專案的檢測,網上一搜就能出現一大堆。

但是,我們開頭介紹資料型別的時候就已經說過了,es6新增了symbol型別,情況好像就有點不一樣了

symbol是es6中引入的原始資料型別。symbol值通過symbol函式生成,是獨一無二的。同時,es6中規定了物件的屬性名有兩種型別,一種是字串,另一種就是symbol型別。凡是屬性名屬於 symbol 型別,就不會與其他屬性名產生衝突。但是,隨之而來的問題是,我們的for...in迴圈不能遍歷出該屬性

symbol作為屬性名,該屬性不會出現在for...infor...of迴圈中,也不會被object.keys()object.getownpropertynames()json.stringify()返回。但是,它也不是私有屬性,有乙個object.getownpropertysymbols方法,可以獲取指定物件的所有 symbol 屬性名。
symbol型別,自然有遍歷symbol型別的方法。object.getownpropertysymbols+for...in的組合起來好像是能滿足我們要求的了。嗯,看起來還不錯,但是似乎有點麻煩了,有沒有更便捷一點的方式呢?或許新時代的男人---reflect.ownkeys,要閃亮登場了,這個既能遍歷字串,又能遍歷symbol的死**(請允許我這麼誇他)。

reflect.ownkeys返回乙個陣列,包含物件自身的所有屬性,不管是屬性名是symbol或字串,也不管是否可列舉
這個時候熟悉es6的人或許開始有疑問了,我們已經開始討論symbolreflect.ownkeys,為什麼淺轉殖不直接用object.assign或者展開運算子(...)呢?

嗯,待我吃根火腿冷靜冷靜,好像你說的很對!object.assign的確是能拷貝symbol型別的呢。但是呢,但是呢,我們是乙個有追求的猿類,多一種實現方式不是能讓我們多了解一些坑嗎?而且這種方式不是能讓我們更靈活的實現不可預知的需求嗎?對,沒錯,是這樣子的...

object.assign這個更完美的男人出來之後,好像淺拷貝部分也該結束了,正常來說,的確是這樣。不過我們再仔細想想上面的兩種方式,好像還是有點區別的呢。我們再來看看這兩個男人:

注意到了嗎?這裡面有乙個是否可列舉的概念,這個時候是不是應該感慨我們知道怎麼實現不可預知的需求了呢。

我們先看個例子:

var obj = object.create(, ,

bar: ,

[symbol()]: ,

baz:

})object.assign({}, obj) //

唉,的確是這樣呢!看來object.assign也不是我們的理想歸宿啊。我們再回過頭來看看reflect.ownkeys,上面挖的坑也該填了,我們在講symbol的時候,object.getownpropertysymbols+for...in直接用reflect.ownkeys替代了,在從可列舉的角度出發看看,好像**不對,for...in只能迴圈遍歷物件自身的和繼承的可列舉的屬性,且不含symbol。頭都大了嗎?來來來,喝完這杯,還有一杯,繼續接著來。這麼多迴圈,我們來縷縷頭緒:

終於清晰了,或許也該結束了吧。

慢著,好像上面的例子讓我想到了什麼!!!

我們在來思考乙個例子:

const source = 

};const target = {};

object.assign(target, source) //

好像並不是我們想要的呢,遍歷的方式好像也不適用了,這可怎麼辦。別急,還有object.getownpropertydescriptors可以用。

es2017 引入了object.getownpropertydescriptors方法,返回指定物件所有自身屬性(非繼承屬性)的描述物件
仔細閱讀下文件,終於用object.getownpropertydescriptors+object.getprototypeof成功了呢

object.create(

object.getprototypeof(obj),

object.getownpropertydescriptors(obj)

)

寫到這裡,淺拷貝部分也該結束了

可能實際專案中並不需要處理的這麼細緻,但是希望大家對各種遍歷、實現乙個淺拷貝以及es6的一些知識有乙個總結和一點新的認識吧,本來想繼續寫深拷貝的,無賴篇幅已經不短,加上長夜漫漫,我想睡覺,深拷貝的問題更複雜,我先放放,日後再說。

ES6要會結構

解構賦值是對賦值運算子的擴充套件。他是一種針對陣列或者物件進行模式匹配,然後對其中的變數進行賦值。在 書寫上簡潔且易讀,語義更加清晰明了 也方便了複雜物件中資料字段獲取。在解構中,有下面兩部分參與 解構的源,解構賦值表示式的右邊部分。解構的目標,解構賦值表示式的左邊部分。陣列模型的解構 array ...

工業4 0時代,你Out了嗎?

新時代到來,有些人享受著資訊化給我們帶來的便利,有些人依然活在自己傳統的思想理論中,不願嘗試新鮮事物,有些人願意去學習,慢慢適應這個飛速發展的資訊化時代。我是媽媽的孩子,我是 1歲侄女的小姨,這個年齡的我選擇了跟著資訊化的腳步走。回想我第一次接觸資訊化的工具,那還是自己第一次去網咖,第一次申請 qq...

es6新特性概括 面試你不愁

1 新增了塊級作用域 由 let const 定義時生成 let和const的區別 let可以宣告變數不賦值 const宣告必須賦值 let宣告的變數可以改變 const一經賦值不能改變 他們都不支援預解析 2 新增了箭頭函式 對函式表示式的簡寫形式 this指向上下文 沒有arguments 所有...