ES6 對象的擴展和新增方法

一、屬性的簡潔表示法

ES6允許在大括號里面直接寫入變量和函數(shù)驱敲,作為對象的屬性和方法。
如下:變量foo直接寫在大括號宽闲,屬性名就是變量名众眨,屬性值就是變量值。

  • 簡寫的對象方法不能用作構(gòu)造函數(shù)容诬,會報錯
const foo = "bar";
const baz = {foo};
console.log(baz); // =>  {foo:"bar"}

// 等同于
const baz = {foo:foo}
// 自己使用場景
const {dataSource} = this.props;
this.setState({dataSource});

function getPoint() {
  const x = 1;
  const y = 10;
  return {x, y};
}

方法也可以簡寫

const o = {
  init(){
    console.log('Hello Word!');
  }
}
const obj = {
  f() {
    this.foo = 'bar';
  }
};

new obj.f() // 報錯

二娩梨、super 關(guān)鍵字

this關(guān)鍵字總是指向函數(shù)所在的當(dāng)前對象
super關(guān)鍵字指向當(dāng)前對象的原型對象
super表示原型對象時,只能用在對象的方法中览徒,用在其它地方都會報錯

const o = {
  h:"Hello"
}
const p = {
  h:"Word",
  find() {
    return super.h
  }
}
Object.setPrototypeOf(p, o);
p.find() // "hello"

三狈定、鏈判斷運算符

在編程實務(wù)中,如果讀取對象內(nèi)部的某個屬性,為了安全我們需要判定一下該對象是否存在

var o = {
  x:1,
  y:2
}

var a = o && o.x ;
// => undefined
var b = o && o.z;
// => undefined

或者使用三元運算符?:纽什,判斷一個對象是否存在

var a = o ? o.x : 10;

如上兩種方式措嵌,如果層次深判斷起來非常麻煩,因此ES2020引入了“鏈判斷運算符”?.

  • 直接在鏈?zhǔn)秸{(diào)用的時候判斷芦缰,左側(cè)的對象是否nullundefined铅匹,如果是,就不再往下運算饺藤,返回undefined包斑。
var o = {
  x:1,
  y:2,
  z:{
    w:3
  }
}
var a  = o?.z?.w;

使用這個運算符,有幾個注意點:
1涕俗、短路機制

a?.[++x];
// 等同于
a == null ? undefined : a[++x];

如果aundefinednull罗丰,那么x不會進(jìn)行遞增運算,也就是說再姑,鏈判斷運算符一旦為真萌抵,右側(cè)的表達(dá)式就不再求值。
2元镀、delete 運算符

delete a?.b
// 等同于
a == null ? undefined ?  delete a.b;

3绍填、括號的影響
如果屬性鏈有圓括號,鏈判斷運算符對圓括號外部沒有影響栖疑,只對圓括號內(nèi)部有影響讨永。

(a?.b).c
// 等同于
(a == null ? undefined : a.b).c

4、報錯場合(以下寫法是禁止的)

// 構(gòu)造函數(shù)
new a?.()
new a?.b()
// 鏈判斷運算符的右側(cè)有模板字符串
a?.`遇革`
a?.b`{c}`
// 鏈判斷運算符的左側(cè)是 super
super?.()
super?.foo
// 鏈運算符用于賦值運算符左側(cè)
a?.b = c

5卿闹、右側(cè)不得為十進(jìn)制數(shù)值
為了兼容以前代碼,?.后邊緊跟一個十進(jìn)制的數(shù)組萝快,那么?.不再被看成一個完整的運算符锻霎,而會按照三元運算符進(jìn)行處理,那個小數(shù)點會歸屬后面的十進(jìn)制數(shù)字揪漩,形成一個小數(shù)旋恼。

a?.3:0
// 被解析成
a ? .3 : 0

四、Null 判斷運算符

讀取對象屬性的時候奄容,如果某個屬性值是nullundefined冰更,有時候需要為它們指定默認(rèn)值,常見的做法是通過||運算符指定默認(rèn)值嫩海。

var o = {
  x:0,
  t:"",
  s:false
}
var a = o.x || 200;   // => 200
var b = o.t || "word"; // => "word"
var c = o.s || true;   // => true

上述三行代碼都是通過||運算符指定默認(rèn)值冬殃,但是這樣寫是錯誤的囚痴,開發(fā)者的意愿是叁怪,只要屬性的值為nullundefined,默認(rèn)值就會生效深滚,但是如果屬性值為0或空字符或false奕谭,默認(rèn)值也會生效涣觉。
為了避免上述情況,ES2020引入了一個新的Null判斷運算符?
它的行為類似||血柳,但是只有運算符左側(cè)的值為nullundefined官册,才會返回右側(cè)的值。

var a = o.x ?? 200;     // => 0
var b = o.t ?? "word"; // => ""
var c = o.s ?? true;   // => false

??有一個運算符優(yōu)先級問題难捌,它與&&||的優(yōu)先級孰高孰低膝宁?現(xiàn)在的規(guī)則是,如果多個邏輯運算符一起使用根吁,必須用括號表明優(yōu)先級员淫,否則會報錯。


五击敌、對象新增方法

1介返、Object.is()

ES6提出同值相等算法,在所有環(huán)境中沃斤,只要兩個值是一樣的圣蝎,它們就應(yīng)該相等,Object.is()用來比較兩個值是否嚴(yán)格相等衡瓶,與嚴(yán)格比較運算符===的行為基本一致徘公。

var o = {
  x:0,
  y:0
}
Object.is(o.x,o.y); // => true

===不同之處在于

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

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

2、Object.assign()

基本用法
Object.assign方法用于對象的合并哮针,將源對象的所有可枚舉屬性步淹,復(fù)制到目標(biāo)對象。

  • 第一個參數(shù)是目標(biāo)對象
  • 后面的參數(shù)都是源對象
var target = {};
var source = {a:1,b:2};
Object.assign(target,source); 
target // => {a:1, b:2, c:3}
  • 如果目標(biāo)對象與源對象有同名屬性诚撵,或多個源對象有同名屬性缭裆,后面的屬性會覆蓋前面的屬性。
var target = {a:1,c:4};
var source = {a:2,b:3};
Object.assign(target,source); 
target // => {a:2,c:4,b:3}  相同的a屬性被覆蓋
  • 如果只有一個參數(shù)寿烟,Object.assign會直接返回該參數(shù)
var o = {a:1};
Object.is(o,Object.assign(o)); // true
  • 如果該參數(shù)不是對象澈驼,則會先轉(zhuǎn)成對象,然后返回
typeof Object.assign(2) // "object"
  • 由于undefined和null無法轉(zhuǎn)成對象筛武,所以如果它們作為參數(shù)缝其,直接報錯。
Object.assign(undefined); 
Object.assign(null);
// TypeError: Cannot convert undefined or null to object
  • 如果非對象參數(shù)出現(xiàn)在源對象的位置徘六,這些參數(shù)會轉(zhuǎn)成對象内边,如果無法轉(zhuǎn)成對象,就會跳過待锈。
var o = {a: 1};
Object.assign(obj, undefined) === obj // true
Object.assign(obj, null) === obj // true

注意點:

  • 淺拷貝
    Object.assign()實現(xiàn)的是淺拷貝漠其,如果源對象的某個屬性值是對象,那么目標(biāo)對象拷貝得到的是這個對象的引用。
var o1 = {a:{b:1}};
var o2 = Object.assign({},o1);
o2.a.b = 2;
o1.a.b; // => 2
  • 同名屬性的替換
var target = {a:1,b:2};
var source = {a:"word"};
Object.assign(target,source);
// {a:"word",b:2}
  • 數(shù)組的處理
    Object.assign()可以處理數(shù)組和屎,但是會把數(shù)組視為對象拴驮。
Object.assign([1, 2, 3], [4, 5])
// [4, 5, 3]

// 實際執(zhí)行的是
Object.assign({0:1,1:2,2:3},{0:4,1:5});
// 根據(jù)同名替換原則輸出的是:{0:4,1:5,2:3}
Array.from({0:4,1:5,2:3,length:3});
// [4,5,3]
  • 取值函數(shù)的處理
    Object.assign()只能進(jìn)行值的復(fù)制,如果要復(fù)制的值是一個取值函數(shù)柴信,那么將求值后再復(fù)制套啤。
var target = {}
var source = {
  get x () { return 1 }
}
Object.assign(target,source);
// => {x:1}

常用途徑:

  • 為對象添加屬性
class Point {
  constructor(x,y){
    Object.assign(this,{x,y}); // 屬性的簡潔表示法
  }
}
var point = new Point(1,2);
// {x:1,y:2};
point instanceof Point; // => true  point 是 類 Point 的實例
point instanceof Object; // => true 所有對象都是Object的實例
  • 合并多個對象
    將對象合并后返回一個新對象
var o1 = {x:1};
var o2 = {y:2};
var merge = (...sources) => Object.assign({}, ...sources); // 合并函數(shù)
var newObj = merge(o1,o2);
// => {x:1,y:2}

3、__proto__屬性

__proto__屬性(前后個兩個下劃線)随常,用來讀取或設(shè)置當(dāng)前對象的prototype對象潜沦,目前,所有瀏覽器(包括IE11)都部署了這個屬性绪氛。
實現(xiàn)上止潮,__proto__調(diào)用的是Object.prototype.__proto__

該屬性并沒有寫入ES6的正文钞楼,而是附錄喇闸,原因是__proto__前后的雙下劃線,說明它本質(zhì)是一個內(nèi)部屬性询件,而不是對外的API燃乍。因此,無論是從語義角度宛琅,還是從兼容角度刻蟹,都不要使用,而是用下邊的代替嘿辟。
Object.setPrototypeOf()(寫入)
Object.getPrototyprOf()(讀扔弑瘛)
Object.create()(生成)

Object.setPrototypeOf()用來設(shè)置一個對象的prototype對象,返回參數(shù)本身

  • 如果第一個參數(shù)是undefinednull 红伦,會報錯英古。
// 格式
Object.setPrototypeOf(object, prototype)

// 實際使用
var p = {};
var o = {x:1};
Object.setPrototypeOf(o,p); // 將p對象設(shè)置為o對象的原型
p.y = 2;
p.z = 3;

"x" in o; // => true 自有屬性
"y" in o; // => true 繼承原型對象屬性
"z" in o; // => true 繼承原型對象屬性

Object.getPrototypeOf()用來讀取一個對象的原型對象

  • 如果第一個參數(shù)是undefinednull ,會報錯昙读。
var p = {x:1};
var o = Object.create(p);
Object.getPrototypeOf(o);
// {x:1}
Object.is(Object.getPrototypeOf(o),p); 
// true

4召调、Object.keys()

  • 返回數(shù)組
  • 數(shù)組成員是參數(shù)對象自身所有可遍歷的屬性的鍵名
  • 不返回繼承的屬性
  • 可以使用for ... of 循環(huán)使用
var o = { a:1, b:2 ,c:3};
Object.keys(o);  // => ["a","b","c"]

for (let key of Object.keys(o)) {
  console.log(key); 
}
// => "a"
// => "b"
// => "c"

5、Object.values()

  • 返回數(shù)組
  • 數(shù)組成員是參數(shù)對象自身所有可遍歷屬性的鍵值
  • 不返回繼承屬性
  • 可以使用for ... of 循環(huán)使用
var o = { a:1, b:2 ,c:3};
Object.values(o);  // => [1,2,3]

for (let value of Object.values(obj)) {
  console.log(value); 
}
// => 1
// => 2
// => 3
  • 會過濾屬性名為Symbol值的屬性
Object.values({ [Symbol()]: 123, foo: 'abc' });
// ['abc']
  • 如果參數(shù)是一個字符串
Object.values('abc');
// => ["a","b","c"]
// 字符串會先轉(zhuǎn)成一個類似數(shù)組的對象如下
Object.keys("abc");
// ["0","1","2"];
Object.values({0:"a",1:"b",2:"c"});
  • 如果參數(shù)不是對象蛮浑,會先轉(zhuǎn)成對象唠叛,由于數(shù)值和布爾值的包裝對象,都不會為實例添加非繼承的屬性沮稚,所以返回空數(shù)組
Object.values(42); // => []
Object.values(true); // => []

6艺沼、Object.entries()

  • 返回一個數(shù)組
  • 數(shù)組成員是參數(shù)對象自身所有可編輯屬性的鍵值對數(shù)組
  • 其他行為與Object.values()基本一致
var o = { a:1, b:2 ,c:3};
Object.entries(o);
// => [["a",1],["b",2],["c",3]]
for (let [key, value] of entries(o)) {
  console.log([key, value]); 
}
// => ['a', 1]
// => ['b', 2]
// => ['c', 3]

7、Object.fromEntries()

此方法是Object.entries()的逆操作蕴掏,用于將一個鍵值對數(shù)組轉(zhuǎn)為對象障般。

Object.fromEntries([["a",1],["b",2],["c",3]]);
// { a:1, b:2 ,c:3}
  • 將Map結(jié)構(gòu)轉(zhuǎn)為對象
var map = new Map().set("a",1).set("b",2);
Object.fromEntries(map);
// {a:1,b:2}
  • 配合URLSearchParams對象调鲸,將查詢字符串轉(zhuǎn)為對象
Object.fromEntries(new URLSearchParams('a=1&b=2'))
// { a: "1", b:"2" }

Object.fromEntries(new URLSearchParams(window.location.search))
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市剩拢,隨后出現(xiàn)的幾起案子线得,更是在濱河造成了極大的恐慌饶唤,老刑警劉巖徐伐,帶你破解...
    沈念sama閱讀 216,496評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異募狂,居然都是意外死亡办素,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評論 3 392
  • 文/潘曉璐 我一進(jìn)店門祸穷,熙熙樓的掌柜王于貴愁眉苦臉地迎上來性穿,“玉大人,你說我怎么就攤上這事雷滚⌒柙” “怎么了?”我有些...
    開封第一講書人閱讀 162,632評論 0 353
  • 文/不壞的土叔 我叫張陵祈远,是天一觀的道長呆万。 經(jīng)常有香客問我,道長车份,這世上最難降的妖魔是什么谋减? 我笑而不...
    開封第一講書人閱讀 58,180評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮扫沼,結(jié)果婚禮上出爹,老公的妹妹穿的比我還像新娘。我一直安慰自己缎除,他們只是感情好严就,可當(dāng)我...
    茶點故事閱讀 67,198評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著器罐,像睡著了一般盈蛮。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上技矮,一...
    開封第一講書人閱讀 51,165評論 1 299
  • 那天抖誉,我揣著相機與錄音,去河邊找鬼衰倦。 笑死袒炉,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的樊零。 我是一名探鬼主播我磁,決...
    沈念sama閱讀 40,052評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼孽文,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了夺艰?” 一聲冷哼從身側(cè)響起芋哭,我...
    開封第一講書人閱讀 38,910評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎郁副,沒想到半個月后减牺,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,324評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡存谎,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,542評論 2 332
  • 正文 我和宋清朗相戀三年拔疚,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片既荚。...
    茶點故事閱讀 39,711評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡稚失,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出恰聘,到底是詐尸還是另有隱情句各,我是刑警寧澤,帶...
    沈念sama閱讀 35,424評論 5 343
  • 正文 年R本政府宣布晴叨,位于F島的核電站凿宾,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏篙螟。R本人自食惡果不足惜菌湃,卻給世界環(huán)境...
    茶點故事閱讀 41,017評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望遍略。 院中可真熱鬧惧所,春花似錦、人聲如沸绪杏。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蕾久。三九已至势似,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間僧著,已是汗流浹背履因。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留盹愚,地道東北人栅迄。 一個月前我還...
    沈念sama閱讀 47,722評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像皆怕,于是被迫代替她去往敵國和親毅舆。 傳聞我的和親對象是個殘疾皇子西篓,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,611評論 2 353

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