ความแตกต่างระหว่างObject.getOwnPropertyNamesและObject.keysในจาวาสคริปต์คืออะไร? นอกจากนี้ยังมีตัวอย่างที่น่าชื่นชม
ความแตกต่างระหว่างObject.getOwnPropertyNamesและObject.keysในจาวาสคริปต์คืออะไร? นอกจากนี้ยังมีตัวอย่างที่น่าชื่นชม
คำตอบ:
มีความแตกต่างเล็กน้อย Object.getOwnPropertyNames(a)ผลตอบแทนที่ได้ทุกaคุณสมบัติของตัวเองของวัตถุ Object.keys(a)ส่งคืนคุณสมบัติทั้งหมดที่นับได้ หมายความว่าหากคุณกำหนดคุณสมบัติวัตถุของคุณโดยไม่ทำให้enumerable: falseทั้งสองวิธีนี้จะให้ผลลัพธ์ที่เหมือนกัน
ทดสอบง่าย:
var a = {};
Object.defineProperties(a, {
one: {enumerable: true, value: 'one'},
two: {enumerable: false, value: 'two'},
});
Object.keys(a); // ["one"]
Object.getOwnPropertyNames(a); // ["one", "two"]
หากคุณกำหนดคุณสมบัติโดยไม่ระบุตัวบอกคุณสมบัติของคุณสมบัติ (หมายถึงคุณไม่ได้ใช้Object.defineProperties) ตัวอย่างเช่น:
a.test = 21;
จากนั้นคุณสมบัติดังกล่าวจะนับโดยอัตโนมัติและทั้งสองวิธีสร้างอาร์เรย์เดียวกัน
length Object.keys
lengthคุณสมบัติของออบเจกต์อยู่บนต้นแบบไม่ใช่ตัวของมันเองดังนั้นจะไม่มีObject.keysและObject.getOwnPropertyNamesจะไม่แสดงรายการ
Object.getOwnPropertyNames(anyArray)รวมlength
Object.getOwnPropertyNames(anyArray)รวมlengthอยู่ในอาร์เรย์ที่ส่งคืนแล้ว!
แตกต่างก็คือในกรณีของอาร์เรย์วิธีการจะกลับคุณสมบัติพิเศษที่เป็นObject.getOwnPropertyNameslength
var x = ["a", "b", "c", "d"];
Object.keys(x); //[ '0', '1', '2', '3' ]
Object.getOwnPropertyNames(x); //[ '0', '1', '2', '3', 'length' ]
สัญกรณ์ตัวอักษร vs ตัวสร้างเมื่อสร้างวัตถุ นี่คือสิ่งที่ทำให้ฉัน
const cat1 = {
eat() {},
sleep() {},
talk() {}
};
// here the methods will be part of the Cat Prototype
class Cat {
eat() {}
sleep() {}
talk() {}
}
const cat2 = new Cat()
Object.keys(cat1) // ["eat", "sleep", "talk"]
Object.keys(Object.getPrototypeOf(cat2)) // []
Object.getOwnPropertyNames(cat1) // ["eat", "sleep", "talk"]
Object.getOwnPropertyNames(Object.getPrototypeOf(cat2)) // ["eat", "sleep", "talk"]
cat1 // {eat: function, sleep: function, talk: function}
cat2 // Cat {}
// a partial of a function that is used to do some magic redeclaration of props
function foo(Obj) {
var propNames = Object.keys(Obj);
// I was missing this if
// if (propNames.length === 0) {
// propNames = Object.getOwnPropertyNames(Obj);
// }
for (var prop in propNames) {
var propName = propNames[prop];
APIObject[propName] = "reasign/redefine or sth";
}
}
ดังนั้นในกรณีของฉันfooฟังก์ชั่นไม่ทำงานถ้าฉันให้วัตถุประเภท cat2
มีวิธีอื่นในการสร้างวัตถุดังนั้นอาจมีจุดบกพร่องอื่น ๆ ในนั้นเช่นกัน
Object.getOwnPropertyNamesจะกลับมาชื่อคุณสมบัติสำหรับการและไม่ได้cat1 cat2สองวิธีในการสร้างวัตถุที่ไม่ก่อให้เกิดความแตกต่างระหว่างและObject.getOwnPropertyNames Object.keys
ตามที่ได้อธิบายไปแล้ว.keysจะไม่ส่งคืนคุณสมบัติที่นับได้
เกี่ยวกับตัวอย่างหนึ่งในกรณีหลุมพรางคือErrorวัตถุ: คุณสมบัติบางอย่างของมันนับได้
ดังนั้นในขณะที่console.log(Object.keys(new Error('some msg')))อัตราผลตอบแทน[],
console.log(Object.getOwnPropertyNames(new Error('some msg')))อัตราผลตอบแทน["stack", "message"]
console.log(Object.keys(new Error('some msg')));
console.log(Object.getOwnPropertyNames(new Error('some msg')));
ข้อแตกต่างอีกอย่างคือ (อย่างน้อยกับ nodejs) ฟังก์ชั่น "getOwnPropertyNames" ไม่รับประกันการสั่งซื้อกุญแจนั่นคือสาเหตุที่ฉันมักจะใช้ฟังก์ชั่น "keys":
Object.keys(o).forEach(function(k) {
if (!o.propertyIsEnumerable(k)) return;
// do something...
});
getOwnPropertyNamesไม่เป็นไปตามลำดับหรือไม่ เนื่องจาก ES2015 ระบุคำสั่งซื้อObect.getOwnPropertyNamesในขณะที่คำสั่งซื้อสำหรับObect.keysยังคงขึ้นอยู่กับการใช้งาน
for-in loop, และObject.keys Object.getOwnPropertyNamesที่กล่าวว่าทั้งสามจะระบุในลำดับที่สอดคล้องกันด้วยความเคารพซึ่งกันและกัน
Object.keys()ไม่สามารถนับได้หรือไม่: จะไม่ส่งคืนในขณะที่Object.getOwnPropertyNames()ทำอยู่