對象的擴展

一巡扇、屬性的簡介表示法

(1)ES6 允許直接寫入變量和函數(shù),作為對象的屬性和方法炊琉。這樣的書寫更加簡潔

const foo = 'bar';
const baz = {foo};
baz // {foo: "bar"}

// 等同于
const baz = {foo: foo};

上面代碼表明展蒂,ES6 允許在對象之中又活,直接寫變量。這時锰悼,屬性名為變量名, 屬性值為變量的值柳骄。下面是另一個例子。

(2)方法簡寫

const o = {
  method() {
    return "Hello!";
  }
};

// 等同于

const o = {
  method: function() {
    return "Hello!";
  }
};

(3)屬性的賦值器(setter)和取值器(getter)簡寫箕般。

const cart = {
  _wheels: 4,

  get wheels () {
    return this._wheels;
  },

  set wheels (value) {
    if (value < this._wheels) {
      throw new Error('數(shù)值太小了耐薯!');
    }
    this._wheels = value;
  }
}

注意,簡潔寫法的屬性名總是字符串丝里,這會導致一些看上去比較奇怪的結(jié)果

const obj = {
  class () {}
};

// 等同于

var obj = {
  'class': function() {}
};

二曲初、屬性名表達式

(1)、JavaScript 定義對象的屬性杯聚,有兩種方法臼婆。

// 方法一
obj.foo = true;

// 方法二
obj['a' + 'bc'] = 123;

上面代碼的方法一是直接用標識符作為屬性名,方法二是用表達式作為屬性名幌绍,這時要將表達式放在方括號之內(nèi)
(2)颁褂、表達式用于定義方法名

let obj = {
  ['h' + 'ello']() {
    return 'hi';
  }
};

obj.hello() // hi

注意,屬性名表達式與簡潔表示法纷捞,不能同時使用痢虹,會報錯。

三主儡、Object.is()比較兩個值是否相等

ES5 比較兩個值是否相等奖唯,只有兩個運算符:相等運算符(==)和嚴格相等運算符(===)世舰。它們都有缺點愕难,前者會自動轉(zhuǎn)換數(shù)據(jù)類型,后者的NaN不等于自身属提,以及+0等于-0寂汇。

Object.is用來比較兩個值是否嚴格相等病往,與(===)的行為基本一致

不同之處只有兩個:一是+0不等于-0,二是NaN等于自身骄瓣。

+0 === -0 //true
NaN === NaN // false

Object.is(+0, -0) // false
Object.is(NaN, NaN) // true

四停巷、Object.assign() 對象合并

1.基本用法

Object.assign將源對象(source)的所有可枚舉屬性,復制到目標對象(target)榕栏。
注意畔勤,如果目標對象與源對象有同名屬性,或多個源對象有同名屬性扒磁,則后面的屬性會覆蓋前面的屬性庆揪。

const target = { a: 1, b: 1 };

const source1 = { b: 2, c: 2 };
const source2 = { c: 3 };

Object.assign(target, source1, source2);
target // {a:1, b:2, c:3}

(1)如果該參數(shù)不是對象,則會先轉(zhuǎn)成對象妨托,然后返回缸榛。

typeof Object.assign(2) // "object"

(2)undefined和null無法轉(zhuǎn)成對象吝羞,所以如果它們作為參數(shù),就會報錯内颗。

Object.assign(undefined) // 報錯
Object.assign(null) // 報錯

(3)非對象參數(shù)出現(xiàn)在源對象的位置(即非首參數(shù))首先钧排,這些參數(shù)都會轉(zhuǎn)成對象,如果無法轉(zhuǎn)成對象起暮,就會跳過卖氨。undefined和null不在首參數(shù)会烙,就不會報錯负懦。

let obj = {a: 1};
Object.assign(obj, undefined) === obj // true
Object.assign(obj, null) === obj // true

(4)其他類型的值(即數(shù)值、字符串和布爾值)不會產(chǎn)生效果

const v1 = 'abc';
const v2 = true;
const v3 = 10;

const obj = Object.assign({}, v1, v2, v3);
console.log(obj); // { "0": "a", "1": "b", "2": "c" }

上面代碼中柏腻,v1纸厉、v2、v3分別是字符串五嫂、布爾值和數(shù)值颗品,結(jié)果只有字符串合入目標對象(以字符數(shù)組的形式),數(shù)值和布爾值都會被忽略沃缘。
Object.assign拷貝的屬性是有限制的躯枢,只拷貝源對象的自身屬性(不拷貝繼承屬性),也不拷貝不可枚舉的屬性

注意點

(1)淺拷貝
Object.assign方法實行的是淺拷貝槐臀,而不是深拷貝

const obj1 = {a: {b: 1}};
const obj2 = Object.assign({}, obj1);

obj1.a.b = 2;
obj2.a.b // 2

上面代碼中锄蹂,obj1的a屬性的值是一個對象,Object.assign拷貝得到的是這個對象的引用
(2)同名屬性的替換

對于這種嵌套的對象水慨,一旦遇到同名屬性得糜,Object.assign的處理方法是替換,而不是添加晰洒。

const target = { a: { b: 'c', d: 'e' } }
const source = { a: { b: 'hello' } }
Object.assign(target, source)
// { a: { b: 'hello' } }

(3)數(shù)組的處理

Object.assign可以用來處理數(shù)組朝抖,但是會把數(shù)組視為對象。

Object.assign([1, 2, 3], [4, 5])
// [4, 5, 3]

上面代碼中谍珊,Object.assign把數(shù)組視為屬性名為 0治宣、1、2 的對象砌滞,因此源數(shù)組的 0 號屬性4覆蓋了目標數(shù)組的 0 號屬性1侮邀。
(4)取值函數(shù)的處理

Object.assign只能進行值的復制,如果要復制的值是一個取值函數(shù)布持,那么將求值后再復制豌拙。

const source = {
  get foo() { return 1 }
};
const target = {};

Object.assign(target, source)
// { foo: 1 }

常見用途

可枚舉性

(1)為對象添加屬性

const source = {
  get foo() { return 1 }
};
const target = {};

Object.assign(target, source)
// { foo: 1 }

上面方法通過Object.assign方法,將x屬性和y屬性添加到Point類的對象實例
(2)為對象添加方法
(3)克隆對象

function clone(origin) {
  return Object.assign({}, origin);
}

上面代碼將原始對象拷貝到一個空對象题暖,就得到了原始對象的克隆按傅。
(4)合并多個對象

將多個對象合并到某個對象捉超。

const merge =
  (target, ...sources) =>     Object.assign(target, ...sources);

五唯绍、屬性的可枚舉性和遍歷

let obj = { foo: 123 };
Object.getOwnPropertyDescriptor(obj, 'foo')
//  {
//    value: 123,
//    writable: true,
//    enumerable: true,
//    configurable: true
//  }

描述對象的enumerable屬性拼岳,稱為”可枚舉性“,如果該屬性為false况芒,就表示某些操作會忽略當前屬性惜纸。
目前,有四個操作會忽略enumerable為false的屬性绝骚。

for...in循環(huán):只遍歷對象自身的和繼承的可枚舉的屬性耐版。
Object.keys():返回對象自身的所有可枚舉的屬性的鍵名。
JSON.stringify():只串行化對象自身的可枚舉的屬性压汪。
Object.assign(): 忽略enumerablefalse的屬性粪牲,只拷貝對象自身的可枚舉的屬性。

屬性的遍歷

(1)for...in

for...in循環(huán)遍歷對象自身的和繼承的可枚舉屬性(不含 Symbol 屬性)止剖。

(2)Object.keys(obj)

Object.keys返回一個數(shù)組腺阳,包括對象自身的(不含繼承的)所有可枚舉屬性(不含 Symbol 屬性)的鍵名。

(3)Object.getOwnPropertyNames(obj)

Object.getOwnPropertyNames返回一個數(shù)組穿香,包含對象自身的所有屬性(不含 Symbol屬性亭引,但是包括不可枚舉屬性)的鍵名。

(4)Object.getOwnPropertySymbols(obj)

Object.getOwnPropertySymbols返回一個數(shù)組皮获,包含對象自身的所有 Symbol 屬性的鍵名焙蚓。

(5)Reflect.ownKeys(obj)

Reflect.ownKeys返回一個數(shù)組,包含對象自身的所有鍵名魔市,不管鍵名是 Symbol或字符串主届,也不管是否可枚舉。

六待德、Object.keys()君丁,Object.values(),Object.entries()

Object.keys() 遍歷屬性的鍵名将宪。

var obj = { foo: 'bar', baz: 42 };
Object.keys(obj)
// ["foo", "baz"]

Object.values()可遍歷屬性的鍵值绘闷。

const obj = { foo: 'bar', baz: 42 };
Object.values(obj)
// ["bar", 42]

Object.entries 可遍歷屬性的鍵值對數(shù)組。

const obj = { foo: 'bar', baz: 42 };
Object.entries(obj)
// [ ["foo", "bar"], ["baz", 42] ]

七较坛、對象的擴展運算符

(1)解構(gòu)賦值

const [a, ...b] = [1, 2, 3];
a // 1
b // [2, 3]

由于解構(gòu)賦值要求等號右邊是一個對象印蔗,所以如果等號右邊是undefined或null,就會報錯丑勤,因為它們無法轉(zhuǎn)為對象华嘹。

let { x, y, ...z } = null; // 運行時錯誤
let { x, y, ...z } = undefined; // 運行時錯誤

解構(gòu)賦值必須是最后一個參數(shù),否則會報錯法竞。

(2)擴展運算符

對象的擴展運算符(...)用于取出參數(shù)對象的所有可遍歷屬性耙厚,拷貝到當前對象之中强挫。

let z = { a: 3, b: 4 };
let n = { ...z };
n // { a: 3, b: 4 }

這等同于使用Object.assign方法。

let aClone = { ...a };
 // 等同于
let aClone = Object.assign({}, a);

如果把自定義屬性放在擴展運算符前面薛躬,就變成了設(shè)置新對象的默認屬性值俯渤。

let aWithDefaults = { x: 1, y: 2, ...a };
// 等同于
let aWithDefaults = Object.assign({}, { x: 1, y: 2 }, a);
// 等同于
let aWithDefaults = Object.assign({ x: 1, y: 2 }, a);

與數(shù)組的擴展運算符一樣,對象的擴展運算符后面可以跟表達式型宝。

const obj = {
  ...(x > 1 ? {a: 1} : {}),
  b: 2,
};

如果擴展運算符后面是一個空對象八匠,則沒有任何效果。

{...{}, a: 1}
// { a: 1 }

如果擴展運算符的參數(shù)是nullundefined趴酣,這兩個值會被忽略梨树,不會報錯。

let emptyObject = { ...null, ...undefined }; // 不報錯
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末价卤,一起剝皮案震驚了整個濱河市劝萤,隨后出現(xiàn)的幾起案子渊涝,更是在濱河造成了極大的恐慌慎璧,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,817評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件跨释,死亡現(xiàn)場離奇詭異胸私,居然都是意外死亡,警方通過查閱死者的電腦和手機鳖谈,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評論 3 385
  • 文/潘曉璐 我一進店門岁疼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人缆娃,你說我怎么就攤上這事捷绒。” “怎么了贯要?”我有些...
    開封第一講書人閱讀 157,354評論 0 348
  • 文/不壞的土叔 我叫張陵暖侨,是天一觀的道長。 經(jīng)常有香客問我崇渗,道長字逗,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,498評論 1 284
  • 正文 為了忘掉前任宅广,我火速辦了婚禮葫掉,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘跟狱。我一直安慰自己俭厚,他們只是感情好,可當我...
    茶點故事閱讀 65,600評論 6 386
  • 文/花漫 我一把揭開白布驶臊。 她就那樣靜靜地躺著挪挤,像睡著了一般绪抛。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上电禀,一...
    開封第一講書人閱讀 49,829評論 1 290
  • 那天幢码,我揣著相機與錄音,去河邊找鬼尖飞。 笑死症副,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的政基。 我是一名探鬼主播贞铣,決...
    沈念sama閱讀 38,979評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼沮明!你這毒婦竟也來了辕坝?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,722評論 0 266
  • 序言:老撾萬榮一對情侶失蹤荐健,失蹤者是張志新(化名)和其女友劉穎酱畅,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體江场,經(jīng)...
    沈念sama閱讀 44,189評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡纺酸,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,519評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了址否。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片餐蔬。...
    茶點故事閱讀 38,654評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖佑附,靈堂內(nèi)的尸體忽然破棺而出樊诺,到底是詐尸還是另有隱情,我是刑警寧澤音同,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布词爬,位于F島的核電站,受9級特大地震影響瘟斜,放射性物質(zhì)發(fā)生泄漏缸夹。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,940評論 3 313
  • 文/蒙蒙 一螺句、第九天 我趴在偏房一處隱蔽的房頂上張望虽惭。 院中可真熱鬧,春花似錦蛇尚、人聲如沸芽唇。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,762評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽匆笤。三九已至研侣,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間炮捧,已是汗流浹背庶诡。 一陣腳步聲響...
    開封第一講書人閱讀 31,993評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留咆课,地道東北人末誓。 一個月前我還...
    沈念sama閱讀 46,382評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像书蚪,于是被迫代替她去往敵國和親喇澡。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,543評論 2 349

推薦閱讀更多精彩內(nèi)容

  • 1. 屬性的間接表示法 ES6 允許直接寫入變量和函數(shù) 除屬性外 方法也可以簡寫 2. 屬性名表達式 ES6 允許...
    MrZhou_b216閱讀 218評論 0 0
  • 屬性的簡潔表示法 ES6 允許直接寫入變量和函數(shù)殊校,作為對象的屬性和方法晴玖。這樣的書寫更加簡潔。 Object.is(...
    小卡丁閱讀 266評論 0 0
  • 一. 屬性的簡潔表示法 ES6 允許直接寫入變量和函數(shù)为流,作為對象的屬性和方法呕屎。這樣的書寫更加簡潔。 這種寫法用于函...
    markpapa閱讀 348評論 0 0
  • 1. 屬性的簡介表示法 ES6允許在對象之中艺谆,只寫屬性名榨惰,不寫屬性值。此時静汤,屬性值等于屬性名所代表的變量。如果某方...
    ForeverYoung20閱讀 1,133評論 0 0
  • 許多父母都會為孩子做作業(yè)慢吞吞而焦急居凶,而許多孩子是做一下虫给,玩一下,快到睡覺時間了還沒做完侠碧,這個時候很多父母會恨鐵不...
    悄然一念閱讀 469評論 0 2