Jaka jest różnica między Object.getOwnPropertyNames
i Object.keys
w javascript? Docenione zostaną również niektóre przykłady.
Jaka jest różnica między Object.getOwnPropertyNames
i Object.keys
w 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: false
te 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ę.
length
właściwości obiektów tablicowych nie są wyliczalne, więc nie pojawiają się w Object.keys
.
length
Właściwość obiektów znajduje się na prototypie, a nie na samym obiekcie, więc ani go Object.keys
nie wymienimy Object.getOwnPropertyNames
.
Object.getOwnPropertyNames(anyArray)
obejmujelength
Object.getOwnPropertyNames(anyArray)
rzeczywiście zawiera length
w 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 foo
funkcja 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.getOwnPropertyNames
zwróci nazwy właściwości dla cat1
i nie cat2
. Dwa sposoby tworzenia obiektu nie powodują różnicy między Object.getOwnPropertyNames
i Object.keys
.
Jak już wyjaśniono, .keys
nie zwraca właściwości policzalnych.
Jeśli chodzi o przykłady, jednym z przypadków pułapek jest Error
obiekt: 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...
});
getOwnPropertyNames
braku 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.