ใน ES6 ได้เพิ่มฟังก์ชัน (หรือเรียกว่าเป็นคลาสเมธอด) ในออบเจ็กต์ Object มาหลายตัว ในบทนี้จะแนะนำฟังก์ชันที่เพิ่มเข้ามาเหล่านั้น
สำหรับฟังก์ชันต่างๆที่เพิ่มเข้ามาตั้งแต่ ES5 แล้วดูได้ใน
บทที่
๒๕ และ
บทที่ ๒๖
Object.assign
Object.assign ใช้รวมพรอเพอร์ตีในออบเจ็กต์ ๒ ตัวขึ้นไปเข้าด้วยกัน
โดยเอาพรอเพอร์ตีจากตัวอื่นๆมาแจกให้กับตัวที่ต้องการ
Object.assign(ออบเจ็กต์ที่จะรับพรอเพอร์ตี, ออบเจ็กต์ที่จะให้พรอเพอร์ตี, ...)
อาร์กิวเมนต์ตัวแรกจะเป็นตัวที่ต้องการรับพรอเพอร์ตี เมื่อใช้ฟังก์ชันนี้เสร็จออบเจ็กต์ตัวนี้ก็จะเปลี่ยนไปทันที
โดยจะได้พรอเพอร์ตีจากออบเจ็กต์ที่วางอยู่ในลำดับถัดๆไป จะใส่กี่ตัวก็ได้
ตัวอย่าง
let suanSiri = { mamuang: 30, taengmo: 20 };
let suanSutrit = { lamyai: 15 };
let suanSanchai = { som: 45, kluai: 300 };
Object.assign(suanSiri, suanSutrit, suanSanchai);
// suanSiri กลายเป็น { mamuang: 30, taengmo: 20, lamyai: 15, som: 45, kluai: 300 };
ที่จะเปลี่ยนแปลงไปมีแค่ออบเจ็กต์ตัวแรกซึ่งเป็นตัวรับพรอเพอร์ตีเท่านั้น ส่วนตัวอื่นจะคงเดิม
หากต้องการสร้างออบเจ็กต์ตัวใหม่ก็อาจใส่ตัวแรกเป็นออบเจ็กต์เปล่า {}
แล้วรับเอาตัวออบเจ็กต์ที่คืนกลับจากฟังก์ชันนี้
let suanKitti = { kaeomangkon: 5, lamut: 35 };
let suanPiti = { thurian: 15, sapparot: 30};
let suanMai = Object.assign({}, suanKitti, suanPiti);
// ได้ suanMai เป็น { kaeomangkon: 5, lamut: 35, thurian: 15, sapparot: 30 }
ตัวฟังก์ชันนี้เองจะคืนตัวออบเจ็กต์ที่เป็นตัวรับพรอเพอร์ตีออกมาด้วย
ดังนั้นเมื่อใส่ตัวแรกเป็นออบเจ็กต์เปล่าแบบนี้ก็จะทำให้ได้ออบเจ็กต์ตัวใหม่ที่มีข้อมูลที่ใส่ทั้งหมด
ตัวที่ใส่เป็นตัวแรกนั้นถ้าไม่ใช่ออบเจ็กต์ก็จะถูกสร้างเป็นออบเจ็กต์ขึ้นมา
เช่นถ้าใช้กับตัวเลขก็จะกลายเป็นออบเจ็กต์ตัวเลข คือใช้ได้เหมือนตัวเลขธรรมดา แต่มีพรอเพอร์ตีเพิ่มเติมอยู่ในตัวด้วย
let n = Object.assign(111, {x: 2});
alert(n); // ได้ 111
alert(typeof n); // ได้ object
alert(n.x); // ได้ 2
เพียงแต่กรณีแบบนี้สิ่งที่ได้จะเป็นออบเจ็กต์ใหม่ ไม่ได้ถูกทับลงในตัวแปรเก่า ตัวแปรเก่าก็จะยังเป็นตัวเดิม
ต้องใช้ตัวแปรอีกตัวมารับออบเจ็กต์ตัวใหม่ที่ได้นี้
let n = 112;
alert(n === Object.assign(n, { x: 7 })); // ได้ false
let obj = {};
alert(obj === Object.assign(obj, { x: 7 })); // ได้ true
ฟังก์ชันนี้ยังถูกใช้เพื่อคัดลอกออบเจ็กต์ สร้างออบเจ็กต์ที่หน้าตาเหมือนกันแต่เป็นคนละตัวกันขึ้นมาอีกตัว
โดยเขียนแบบนี้
let raiA = {khao: 20, thua: 30};
let raiB = Object.assign({}, raiA);
alert(raiA===raiB); // ได้ false (เพราะถือเป็นคนละออบเจ็กต์กัน)
alert(raiB.khao); // ได้ 20
alert(raiB.thua); // ได้ 30
แต่มีข้อควรระวัง คือเมื่อพรอเพอร์ตีในออบเจ็กต์เองก็เป็นออบเจ็กต์ด้วย แบบนี้จะไม่ใช่การคัดลอกอย่างสมบูรณ์
เพราะออบเจ็กต์ด้านในจะยังเป็นตัวเดียวกันอยู่
let Sanphon = {
suanSom: {som: 200}
};
let Kamphon = Object.assign({}, Sanphon);
alert(Kamphon === Sanphon); // ได้ false (เป็นออบเจ็กต์คนละตัวกัน)
alert(Kamphon.suanSom === Sanphon.suanSom); // ได้ true (เป็นออบเจ็กต์ตัวเดียวกัน)
หากต้องการจะคัดลอกออบเจ็กต์ให้เป็นตัวใหม่ทั้งหมดแม้แต่เนื้อใน แบบนั้นควรใช้ JSON.parse กับ JSON.stringify
แบบที่เขียนถึงใน
บทที่
๒๘
Object.is
ฟังก์ชัน Object.is ใช้ดูว่าค่า ๒ ตัวเท่ากันหรือไม่ คล้ายการใช้ === ในการเปรียบเทียบ
alert(Object.is("ผงขาว", "แป้ง")); // ได้ false
alert(Object.is('แป้ง', "แป้ง")); // ได้ true
alert(Object.is({}, {})); // ได้ false
แต่มีข้อแตกต่างจาก === อยู่บ้าง ในกรณีที่ใช้กับ NaN หรือ 0 โดย Object.is จะถือว่า +0 และ -0 เป็นคนละตัวกัน และถือว่า
NaN ทั้งหมดเป็นตัวเดียวกัน
alert(+0 === -0); // ได้ true
alert(Object.is(+0, -0)); // ได้ false
alert(NaN === NaN); // ได้ false
alert(Object.is(NaN, NaN)); // ได้ true
Object.setPrototypeOf
Object.setPrototypeOf ใช้ตั้งออบเจ็กต์ตัวหนึ่งให้เป็นโพรโทไทป์ของอีกตัวหนึ่ง
เรื่องของโพรโทไทป์ได้เขียนถึงใน
บทที่
๒๑ นอกจากนี้ใน ES5 มีฟังก์ชันคล้ายๆกันคือ Object.getPrototypeOf สำหรับดูตัวโพรโทไทป์ของออบเจ็กต์ กล่าวถึงไปใน
บทที่ ๒๖
วิธีใช้
Object.setPrototypeOf(ออบเจ็กต์, ออบเจ็กต์ที่จะเป็นโพรโทไทป์)
ตัวอย่าง
let mot = {kha: 6};
let motDam = { si: "#000" };
Object.setPrototypeOf(motDam, mot);
mot.pik = 4;
alert(Object.getPrototypeOf(motDam)===mot);
alert(motDam.kha); // ได้ 6
alert(motDam.si); // ได้ #000
alert(motDam.pik); // ได้ 4
mot.kha = 5;
alert(motDam.kha); // ได้ 5
ตัวฟังก์ชันนี้เมื่อใช้แล้วก็มีการคืนตัวออบเจ็กต์กลับมา
ดังนั้นสามารถใช้กับออบเจ็กต์เปล่าเพื่อสร้างออบเจ็กต์ตัวใหม่ที่มีโพรโทไทป์เป็นออบเจ็กต์ที่ต้องการได้ เช่น
let maeo = { kha: 4, hang: 1 };
let maeoDam = Object.setPrototypeOf({}, maeo);
alert(Object.getPrototypeOf(maeoDam) === maeo); // ได้ true
alert(maeoDam.kha); // ได้ 4
Object.getOwnPropertySymbols
ใน
บทที่
๓๕ ได้เขียนถึงข้อมูลชนิดซิมโบล และการใช้ซิมโบลเป็นคีย์ของพรอเพอร์ตีในออบเจ็กต์ไป
ปกติแล้วเวลาใช้ Object.key() เพื่อให้แสดงคีย์ทั้งหมด หรือ for๛in เพื่อวนซ้ำ
พรอเพอร์ตีที่คีย์เป็นซิมโบลจะไม่ได้ถูกไล่ออกมาด้วย
แต่หากต้องการให้แสดงพรอเพอร์ตีที่มีคีย์เป็นซิมโบลทั้งหมดออกมาก็สามารถทำได้โดยใช้ Object.getOwnPropertySymbols()
ตัวอย่าง
const TAMAYA = Symbol();
const KAGIYA = Symbol();
let hanabi = {
[TAMAYA]: "ทามายะ",
[KAGIYA]: "คางิยะ"
};
alert(TAMAYA in hanabi); // ได้ true
alert(KAGIYA in hanabi); // ได้ true
let prosy = Object.getOwnPropertySymbols(hanabi);
alert(prosy.map(s => typeof s)); // ได้ symbol,symbol
alert(prosy.map(s => hanabi[s])); // ได้ ทามายะ,คางิยะ
alert(TAMAYA == prosy[0]); // ได้ true
alert(KAGIYA == prosy[1]); // ได้ true
Object.getOwnPropertyDescriptors [ES2017]
ใน ES5 มีฟังก์ชัน Object.getOwnPropertyDescriptor() สำหรับดูคำอธิบายคุณสมบัติของพรอเพอร์ตีซึ่งสามารถตั้งขึ้นมาจาก
Object.definePropertie หรือ Object.defineProperties (รายละเอียด
บทที่
๒๖)
สำหรับใน ES2017 ได้เพิ่ม Object.getOwnPropertyDescriptors()
เอาไว้แสดงคำอธิบายของพรอเพอร์ตีทั้งหมดที่มีอยู่ในออบเจ็กต์ออกมาทั้งหมด
ซึ่งรวมถึงพรอเพอร์ตีที่ชื่อคีย์เป็นซิมโบลด้วย
ตัวอย่าง
const ATK = Symbol();
let puenyai = { nak: 2000 };
Object.defineProperties(puenyai, {
yao: {
value: 5,
writable: false,
enumerable: true
},
[ATK]: {
value: 999,
configurable: true
}
});
let prodes = Object.getOwnPropertyDescriptors(puenyai);
alert(prodes[ATK].value); // ได้ 999
alert(prodes.yao.value); // ได้ 5
alert(prodes.nak.value); // ได้ 2000
alert(prodes.yao.writable); // ได้ false
alert(prodes[ATK].configurable); // ได้ true
alert(prodes.yao.enumerable); // ได้ true
Object.values และ Object.entries [ES2017]
ใน ES5 มีฟังก์ชัน Object.keys ไว้สำหรับไล่ดูชื่อคีย์ของพรอเพอร์ตีทั้งหมดออกมาเป็นแถวลำดับ ดังที่เขียนไปใน
บทที่ ๒๖
ใน ES2017 ได้เพิ่มฟังก์ชัน Object.values ไว้สำหรับดูค่า และ Object.entries สำหรับดูคีย์และค่าพร้อมกัน
วิธีการใช้คล้ายกับเมธอด .keys .values .entries ในแถวลำดับซึ่งได้เขียนถึงไปใน
บทที่ ๔๖
แต่เป็นฟังก์ชันที่ใช้กับออบเจ็กต์ใดๆก็ได้
ตัวอย่างการใช้
let hanayamata = {
naru: 150,
hana: 144,
yaya: 158,
tami: 155,
machi: 163
};
alert(Object.keys(hanayamata)); // ได้ naru,hana,yaya,tami,machi
alert(Object.values(hanayamata)); // ได้ 150,144,158,155,163
let ent = Object.entries(hanayamata);
alert(ent.length); // ได้ 5
alert(ent[0]); // ได้ naru,150
alert(ent[1]); // ได้ hana,144
alert(ent[2]); // ได้ yaya,158
alert(ent[3]); // ได้ tami,155
ทั้ง Object.keys, Object.values และ Object.entries จะไม่แสดงพรอเพอร์ตีที่ไม่สามารถไล่เรียงได้ (enumerable เป็น false)
รวมถึงที่คีย์เป็นซิมโบล
Object.fromEntries [ES2019]
Object.fromEntries เพิ่มเข้ามาใน ES2019 เป็นฟังก์ชันที่ทำงานตรงกันข้ามกับ Object.entries
คือจะสร้างออบเจ็กต์ขึ้นมาจากแถวลำดับของคู่คีย์และค่าพรอเพอร์ตี
ตัวอย่างการใช้
let ent = [
["hinako", 160],
["mayuki", 139],
["kuina", 155],
["chiaki", 169],
["yua", 158],
];
let hinakonote = Object.fromEntries(ent);
alert(hinakonote.yua); // ได้ 158
alert(Object.keys(hinakonote)); // ได้ hinako,mayuki,kuina,chiaki,yua
alert(Object.values(hinakonote)); // ได้ 160,139,155,169,158
สรุปฟังก์ชันทั้งหมด
ชื่อฟังก์ชัน |
ความสามารถ |
เพิ่มมาใน |
Object.assign |
แจกพรอเพอร์ตีจากออบเจ็กต์อื่นให้ออบเจ็กต์ตัวหนึ่ง |
ES2015 |
Object.is |
เทียบว่าออบเจ็กต์หรือตัวแปร ๒ ตัวมีค่าเท่ากันหรือเปล่า |
Object.setPrototypeOf |
ตั้งโพรโทไทป์ให้ออบเจ็กต์ |
Object.getOwnPropertySymbols |
แสดงพรอเพอร์ตีที่ใช้คีย์เป็นซิมโบลทั้งหมด |
Object.getOwnPropertyDescriptors |
แสดงพรอเพอร์ตีทั้งหมด |
ES2017 |
Object.values |
แสดงค่าทั้งหมดของพรอเพอร์ตีในออบเจ็กต์ |
Object.entries |
แสดงคีย์ทั้งหมดของพรอเพอร์ตีในออบเจ็กต์ |
Object.fromEntries |
แสดงคีย์และค่าทั้งหมดของพรอเพอร์ตีในออบเจ็กต์ |
ES2019 |