對象屬性遍歷贫贝,就是要搞清楚 哪些屬性可以遍歷秉犹,哪些屬性不能遍歷。
對象復(fù)制?就是要搞清楚?哪些屬性可以復(fù)制稚晚,哪些屬性不能復(fù)制崇堵。
那么首先要了解的知識?是屬性分類,不同類型的屬性有不同的行為客燕。
屬性的分類
直接上圖了
不了解類別的可以看我下面的代碼
-------------代碼開始
var sym = Symbol('sym');
? ? ? ? var sym2 = Symbol('sym2');
? ? ? ? var testObj = {
? ? ? ? ? ? a: 1,//數(shù)據(jù)屬性
? ? ? ? ? ? b: 2,
? ? ? ? ? ? [Symbol('symbol屬性')]: 'symbol屬性',//symbol屬性
? ? ? ? ? ? fun: function () { return this.a; },//函數(shù)屬性
? ? ? ? ? ? get Cun() {? ? ? ? ? ? ? ? ? ? //存取器屬性
? ? ? ? ? ? ? ? return 0;
? ? ? ? ? ? },
? ? ? ? ? ? set Cun(val) {
? ? ? ? ? ? ? ? this.a = val;
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? testObj[sym] = 'symbool';
? ? ? ? //獲取數(shù)據(jù)屬性的特性描述符
? ? ? ? let da = Object.getOwnPropertyDescriptor(testObj, 'a');
? ? ? ? console.log('da', da)
? ? ? ? let fa = Object.getOwnPropertyDescriptor(testObj, 'fun');
? ? ? ? console.log('fa', fa)
? ? ? ? //獲取存取器屬性的特性描述符
? ? ? ? let Cun = Object.getOwnPropertyDescriptor(testObj, 'Cun');
? ? ? ? console.log('Cun', Cun)
? ? ? ? let symb = Object.getOwnPropertyDescriptor(testObj, sym);
? ? ? ? console.log('symb', symb)
-----------------復(fù)制這些代碼就能夠了解這些屬性類別了
執(zhí)行后的圖如下
研究遍歷行為
相關(guān)代碼
var sym = Symbol('不可枚舉的symbol屬性');
? ? ? ? var symCun = Symbol('存取的symbol屬性');
? ? ? ? var sym2 = Symbol('sym2');
? ? ? ? var testObj = {
? ? ? ? ? ? a: 1,
? ? ? ? ? ? b: 2,
? ? ? ? ? ? [Symbol('testObj')]: 'testObj',
? ? ? ? ? ? fun: function () { return this.a; },
? ? ? ? ? ? get Cun() {
? ? ? ? ? ? ? ? return 0;
? ? ? ? ? ? },
? ? ? ? ? ? set Cun(val) {
? ? ? ? ? ? ? ? this.a = val;
? ? ? ? ? ? },
? ? ? ? ? ? get [symCun]() {
? ? ? ? ? ? ? ? return '存取的symbol屬性';
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? testObj[sym] = 'symbool';
? ? ? ? Object.defineProperty(testObj, sym, {
? ? ? ? ? ? enumerable: false
? ? ? ? })
? ? ? ? var protoObj = {
? ? ? ? ? ? a1: 1,
? ? ? ? ? ? b2: 2,
? ? ? ? ? ? fun2: function () { return this.a; },
? ? ? ? ? ? set Cun2(val) {
? ? ? ? ? ? ? ? this.a = val;
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? protoObj[sym2] = 'symbool2';
? ? ? ? Object.setPrototypeOf(testObj, protoObj);
? ? ? ? console.log('for in? ------------')
? ? ? ? for (const item in testObj) {
? ? ? ? ? ? console.log(item)
? ? ? ? }
? ? ? ? console.log('Object.keys ------------')
? ? ? ? for (const item of Object.keys(testObj)) {
? ? ? ? ? ? console.log(item)
? ? ? ? }
? ? ? ? console.log('? Object.getOwnPropertyNames ------------')
? ? ? ? for (const item of Object.getOwnPropertyNames(testObj)) {
? ? ? ? ? ? console.log(item)
? ? ? ? }
? ? ? ? console.log(' Object.getOwnPropertySymbols ------------')
? ? ? ? for (const item of Object.getOwnPropertySymbols(testObj)) {
? ? ? ? ? ? console.log(item)
? ? ? ? }
? ? ? ? console.log(testObj, testObj[symCun])
運(yùn)行后的結(jié)果
復(fù)制行為研究
結(jié)果直接上圖
相關(guān)研究代碼
var sym = Symbol('sym');
? ? ? ? var sym2 = Symbol('sym2');
? ? ? ? var deepObj = { deep: 'deep' };
? ? ? ? var testObj = {
? ? ? ? ? ? a: 1,//數(shù)據(jù)屬性
? ? ? ? ? ? b: 2,
? ? ? ? ? ? deepObj: deepObj,
? ? ? ? ? ? [Symbol('testObj')]: 'testObj',//Symbol類型屬性
? ? ? ? ? ? fun: function () { return this.a; },//函數(shù)屬性
? ? ? ? ? ? get Cun() {? ? ? ? ? ? ? ? ? ? //存取器屬性
? ? ? ? ? ? ? ? console.log('讀取get描述符被執(zhí)行')
? ? ? ? ? ? ? ? return 0;
? ? ? ? ? ? },
? ? ? ? ? ? set Cun(val) {
? ? ? ? ? ? ? ? this.a = val;
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? testObj[sym] = 'symbool';
? ? ? ? Object.defineProperty(testObj, 'a', {
? ? ? ? ? ? enumerable: true,
? ? ? ? ? ? configurable: false,
? ? ? ? ? ? writable: false,
? ? ? ? ? ? value: 'John'
? ? ? ? })
? ? ? ? //b屬性被定義為不可枚舉
? ? ? ? Object.defineProperty(testObj, 'b', {
? ? ? ? ? ? enumerable: false,
? ? ? ? ? ? configurable: false,
? ? ? ? ? ? writable: false,
? ? ? ? ? ? value: 'John'
? ? ? ? })
? ? ? ? var protoObj = {
? ? ? ? ? ? a1: 1,
? ? ? ? ? ? b2: 2,
? ? ? ? ? ? fun2: function () { return this.a; },
? ? ? ? ? ? set Cun2(val) {
? ? ? ? ? ? ? ? this.a = val;
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? protoObj[sym2] = 'symbool2';
? ? ? ? Object.setPrototypeOf(testObj, protoObj);
? ? ? ? console.log('原對象', testObj, Object.getOwnPropertyDescriptor(testObj, 'a'), testObj.deepObj === deepObj)
? ? ? ? console.log('...擴(kuò)展符的復(fù)制')
? ? ? ? let copy1 = { ...testObj };
? ? ? ? console.log(copy1, Object.getOwnPropertyDescriptor(copy1, 'a'), '引用對象是否相等', copy1.deepObj === deepObj);
? ? ? ? console.log('Object.assign的復(fù)制');
? ? ? ? copy1 = Object.assign({}, testObj);
? ? ? ? console.log(copy1, Object.getOwnPropertyDescriptor(copy1, 'a'), '引用對象是否相等', copy1.deepObj === deepObj);
? ? ? ? console.log('json化的復(fù)制');
? ? ? ? copy1 = JSON.parse(JSON.stringify(testObj));
? ? ? ? console.log(copy1, Object.getOwnPropertyDescriptor(copy1, 'a'), '引用對象是否相等' + copy1.deepObj === deepObj);
運(yùn)行后結(jié)果
2019-10-19補(bǔ)充
JSON.parse(JSON.stringify(object))?這個復(fù)制方式
會忽略?undefined鸳劳,不能序列化函數(shù),不能解決循環(huán)引用的對象也搓,還有構(gòu)造函數(shù)會發(fā)生變化
有疑問或其他意見的可以評論或qq交流 qq352169715?加我請備注js交流