Jaka jest różnica między Object.getOwnPropertyNamesi Object.keysw javascript? Docenione zostaną również niektóre przykłady.
Jaka jest różnica między Object.getOwnPropertyNamesi Object.keysw javascript? Docenione zostaną również niektóre przykłady.
Odpowiedzi:
Jest mała różnica. Object.getOwnPropertyNames(a)zwraca wszystkie własne właściwości obiektu a. Object.keys(a)zwraca wszystkie wyliczalne własne właściwości. Oznacza to, że jeśli zdefiniujesz właściwości obiektu bez robienia niektórych z nich, enumerable: falsete dwie metody dadzą ci ten sam rezultat.
Łatwo jest przetestować:
var a = {};
Object.defineProperties(a, {
one: {enumerable: true, value: 'one'},
two: {enumerable: false, value: 'two'},
});
Object.keys(a); // ["one"]
Object.getOwnPropertyNames(a); // ["one", "two"]
Jeśli zdefiniujesz właściwość bez podania deskryptora atrybutów właściwości (co oznacza, że nie używasz Object.defineProperties), na przykład:
a.test = 21;
wtedy taka właściwość staje się automatycznie wyliczalna i obie metody tworzą tę samą tablicę.
lengthwłaściwości obiektów tablicowych nie są wyliczalne, więc nie pojawiają się w Object.keys.
lengthWłaściwość obiektów znajduje się na prototypie, a nie na samym obiekcie, więc ani go Object.keysnie wymienimy Object.getOwnPropertyNames.
Object.getOwnPropertyNames(anyArray)obejmujelength
Object.getOwnPropertyNames(anyArray)rzeczywiście zawiera lengthw zwróconej tablicy!
Notacja dosłowna a konstruktor podczas tworzenia obiektu. Oto coś, co mnie dopadło.
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";
}
}
Więc w moim przypadku foofunkcja nie działała, jeśli dałem jej obiekty typu cat2.
Istnieją inne sposoby tworzenia obiektów, więc mogą być też inne zagięcia.
Object.getOwnPropertyNameszwróci nazwy właściwości dla cat1i nie cat2. Dwa sposoby tworzenia obiektu nie powodują różnicy między Object.getOwnPropertyNamesi Object.keys.
Jak już wyjaśniono, .keysnie zwraca właściwości policzalnych.
Jeśli chodzi o przykłady, jednym z przypadków pułapek jest Errorobiekt: niektóre jego właściwości są policzalne.
Tak więc, podczas gdy console.log(Object.keys(new Error('some msg')))plony [],
console.log(Object.getOwnPropertyNames(new Error('some msg')))plony["stack", "message"]
console.log(Object.keys(new Error('some msg')));
console.log(Object.getOwnPropertyNames(new Error('some msg')));
Kolejna różnica polega na tym, że (przynajmniej z nodejs) funkcja „getOwnPropertyNames” nie gwarantuje kolejności kluczy, dlatego zwykle używam funkcji „klucze”:
Object.keys(o).forEach(function(k) {
if (!o.propertyIsEnumerable(k)) return;
// do something...
});
getOwnPropertyNamesbraku porządku? Ponieważ ES2015 określa zamówienie naObect.getOwnPropertyNames , podczas gdy zamówienie naObect.keys wciąż zależy od implementacji.
for-in loop, Object.keys, i Object.getOwnPropertyNames. To powiedziawszy, wszystkie trzy wyliczą w spójnej kolejności względem siebie.
Object.keys()nie zwraca ich, aObject.getOwnPropertyNames()robi to.