Szukaj…
Składnia
- obiekt = {}
- object = new Object ()
- object = Object.create (prototype [, propertiesObject])
- object.key = wartość
- obiekt [„klucz”] = wartość
- obiekt [Symbol ()] = wartość
- object = {klucz1: wartość1, „klucz2”: wartość2, „klucz3”: wartość3}
- object = {conciseMethod () {…}}
- object = {[computed () + "key"]: value}
- Object.defineProperty (obj, propertyName, propertyDescriptor)
- property_desc = Object.getOwnPropertyDescriptor (obj, propertyName)
- Object.freeze (obj)
- Object.seal (obj)
Parametry
własność | Opis |
---|---|
value | Wartość do przypisania do właściwości. |
writable | Określa, czy wartość właściwości można zmienić, czy nie. |
enumerable | Określa, czy właściwość będzie wyliczana for in pętli, czy nie. |
configurable | Czy będzie możliwe ponowne zdefiniowanie deskryptora właściwości, czy nie. |
get | Wywołana funkcja, która zwróci wartość właściwości. |
set | Funkcja, która ma zostać wywołana, gdy właściwość ma przypisaną wartość. |
Uwagi
Obiekty są kolekcjami par klucz-wartość lub właściwości. Przyciski mogą być String
S lub Symbol
s, przy czym wartości są albo wbudowanych (liczbami, nazwami, symbole) i odniesienia do innych przedmiotów.
W JavaScript znaczną ilością wartości są obiekty (np. Funkcje, tablice) lub prymitywy, które zachowują się jak obiekty niezmienne (liczby, ciągi znaków, logiczne). Do ich właściwości lub właściwości ich prototype
można uzyskać dostęp za pomocą notacji kropkowej ( obj.prop
) lub obj.prop
( obj['prop']
). Ważnymi wyjątkami są wartości specjalne undefined
i null
.
Obiekty są przechowywane w JavaScript przez odniesienie, a nie według wartości. Oznacza to, że po skopiowaniu lub przekazaniu jako argumenty funkcji „kopia” i oryginał są odniesieniami do tego samego obiektu, a zmiana właściwości jednej zmieni tę samą właściwość drugiej. Nie dotyczy to prymitywów, które są niezmienne i przekazywane przez wartość.
Object.keys
Object.keys(obj)
zwraca tablicę kluczy danego obiektu.
var obj = {
a: "hello",
b: "this is",
c: "javascript!"
};
var keys = Object.keys(obj);
console.log(keys); // ["a", "b", "c"]
Płytkie klonowanie
Funkcji Object.assign()
w ES6 można użyć do skopiowania wszystkich wyliczalnych właściwości z istniejącej instancji Object
na nową.
const existing = { a: 1, b: 2, c: 3 };
const clone = Object.assign({}, existing);
Obejmuje to właściwości Symbol
oprócz właściwości String
.
Restrukturyzacja odpoczynku / rozprzestrzeniania się obiektów, która jest obecnie propozycją na etapie 3, zapewnia jeszcze prostszy sposób tworzenia płytkich klonów instancji obiektów:
const existing = { a: 1, b: 2, c: 3 };
const { ...clone } = existing;
Jeśli potrzebujesz obsługi starszych wersji JavaScript, najbardziej kompatybilnym sposobem klonowania obiektu jest ręczne iterowanie jego właściwości i filtrowanie odziedziczonych za pomocą .hasOwnProperty()
.
var existing = { a: 1, b: 2, c: 3 };
var clone = {};
for (var prop in existing) {
if (existing.hasOwnProperty(prop)) {
clone[prop] = existing[prop];
}
}
Object.defineProperty
Pozwala nam zdefiniować właściwość w istniejącym obiekcie za pomocą deskryptora właściwości.
var obj = { };
Object.defineProperty(obj, 'foo', { value: 'foo' });
console.log(obj.foo);
Wyjście konsoli
bla
Object.defineProperty
można wywoływać za pomocą następujących opcji:
Object.defineProperty(obj, 'nameOfTheProperty', {
value: valueOfTheProperty,
writable: true, // if false, the property is read-only
configurable : true, // true means the property can be changed later
enumerable : true // true means property can be enumerated such as in a for..in loop
});
Object.defineProperties
umożliwia zdefiniowanie wielu właściwości jednocześnie.
var obj = {};
Object.defineProperties(obj, {
property1: {
value: true,
writable: true
},
property2: {
value: 'Hello',
writable: false
}
});
Właściwość tylko do odczytu
Za pomocą deskryptorów właściwości możemy uczynić właściwość tylko do odczytu, a każda próba zmiany jej wartości zakończy się niepowodzeniem po cichu, wartość nie zostanie zmieniona i nie zostanie zgłoszony żaden błąd.
writable
właściwość w deskryptorze właściwości wskazuje, czy tę właściwość można zmienić, czy nie.
var a = { };
Object.defineProperty(a, 'foo', { value: 'original', writable: false });
a.foo = 'new';
console.log(a.foo);
Wyjście konsoli
oryginalny
Właściwość niepoliczalna
Możemy uniknąć wyświetlania właściwości for (... in ...)
pętli for (... in ...)
enumerable
właściwość deskryptora właściwości informuje, czy ta właściwość będzie wyliczana podczas przechodzenia przez właściwości obiektu.
var obj = { };
Object.defineProperty(obj, "foo", { value: 'show', enumerable: true });
Object.defineProperty(obj, "bar", { value: 'hide', enumerable: false });
for (var prop in obj) {
console.log(obj[prop]);
}
Wyjście konsoli
pokazać
Zablokuj opis właściwości
Deskryptor właściwości można zablokować, aby nie można było w nim dokonywać żadnych zmian. Nadal będzie można normalnie korzystać z właściwości, przypisując i pobierając z niej wartość, ale każda próba przedefiniowania spowoduje zgłoszenie wyjątku.
configurable
właściwość deskryptora właściwości służy do uniemożliwienia jakichkolwiek dalszych zmian w deskryptorze.
var obj = {};
// Define 'foo' as read only and lock it
Object.defineProperty(obj, "foo", {
value: "original value",
writable: false,
configurable: false
});
Object.defineProperty(obj, "foo", {writable: true});
Ten błąd zostanie zgłoszony:
TypeError: Nie można przedefiniować właściwości: foo
A właściwość nadal będzie tylko do odczytu.
obj.foo = "new value";
console.log(foo);
Wyjście konsoli
oryginalna wartość
Właściwości modułu Accesor (pobierz i ustaw)
Traktuj właściwość jako kombinację dwóch funkcji, jednej, aby uzyskać z niej wartość, a drugiej, aby ustawić w niej wartość.
Właściwość get
deskryptora właściwości to funkcja, która zostanie wywołana w celu pobrania wartości z właściwości.
Właściwość set
jest również funkcją, zostanie wywołana, gdy właściwość zostanie przypisana wartość, a nowa wartość zostanie przekazana jako argument.
Nie można przypisać value
ani writable
do deskryptora, który został get
lub set
var person = { name: "John", surname: "Doe"};
Object.defineProperty(person, 'fullName', {
get: function () {
return this.name + " " + this.surname;
},
set: function (value) {
[this.name, this.surname] = value.split(" ");
}
});
console.log(person.fullName); // -> "John Doe"
person.surname = "Hill";
console.log(person.fullName); // -> "John Hill"
person.fullName = "Mary Jones";
console.log(person.name) // -> "Mary"
Właściwości ze znakami specjalnymi lub słowami zastrzeżonymi
Podczas gdy notacja właściwości obiektu jest zwykle zapisywana jako myObject.property
, pozwoli to tylko na znaki, które normalnie znajdują się w nazwach zmiennych JavaScript , czyli głównie litery, cyfry i znak podkreślenia ( _
).
Jeśli potrzebujesz znaków specjalnych, takich jak przestrzeń, ☺ lub treści tworzone przez użytkowników pod warunkiem, jest to możliwe przy użyciu []
notacji nawiasu.
myObject['special property ☺'] = 'it works!'
console.log(myObject['special property ☺'])
Wszystkie właściwości cyfrowe:
Oprócz znaków specjalnych nazwy własności składające się z samych cyfr będą wymagały notacji w nawiasach. Jednak w tym przypadku właściwość nie musi być zapisywana jako ciąg.
myObject[123] = 'hi!' // number 123 is automatically converted to a string
console.log(myObject['123']) // notice how using string 123 produced the same result
console.log(myObject['12' + '3']) // string concatenation
console.log(myObject[120 + 3]) // arithmetic, still resulting in 123 and producing the same result
console.log(myObject[123.0]) // this works too because 123.0 evaluates to 123
console.log(myObject['123.0']) // this does NOT work, because '123' != '123.0'
Jednak początkowe zera nie są zalecane, ponieważ jest to interpretowane jako notacja ósemkowa. (DO ZROBIENIA, powinniśmy stworzyć i połączyć z przykładem opisującym notację ósemkową, szesnastkową i wykładnik)
Zobacz także: Przykład [tablice to obiekty].
Nazwy właściwości dynamicznych / zmiennych
Czasami nazwa właściwości musi być przechowywana w zmiennej. W tym przykładzie pytamy użytkownika, jakie słowo należy wyszukać, a następnie podajemy wynik z obiektu, który nazwałem dictionary
.
var dictionary = {
lettuce: 'a veggie',
banana: 'a fruit',
tomato: 'it depends on who you ask',
apple: 'a fruit',
Apple: 'Steve Jobs rocks!' // properties are case-sensitive
}
var word = prompt('What word would you like to look up today?')
var definition = dictionary[word]
alert(word + '\n\n' + definition)
Zwróć uwagę, w jaki sposób używamy notacji nawiasowej []
aby spojrzeć na zmienną o nazwie word
; gdybyśmy mieli użyć tradycyjnego .
notacja, wówczas przyjąłaby wartość dosłownie, stąd:
console.log(dictionary.word) // doesn't work because word is taken literally and dictionary has no field named `word`
console.log(dictionary.apple) // it works! because apple is taken literally
console.log(dictionary[word]) // it works! because word is a variable, and the user perfectly typed in one of the words from our dictionary when prompted
console.log(dictionary[apple]) // error! apple is not defined (as a variable)
Można również pisać wartości literalne notacją []
, zastępując word
zmienne ciągiem 'apple'
. Zobacz przykład [Właściwości ze znakami specjalnymi lub słowami zastrzeżonymi].
Możesz także ustawić właściwości dynamiczne za pomocą składni nawiasu:
var property="test";
var obj={
[property]=1;
};
console.log(obj.test);//1
Robi to samo co:
var property="test";
var obj={};
obj[property]=1;
Tablice są obiektami
Oświadczenie: Tworzenie obiektów podobnych do tablicy nie jest zalecane. Jednak pomocne jest zrozumienie ich działania, zwłaszcza podczas pracy z DOM. To wyjaśni, dlaczego zwykłe operacje tablicowe nie działają na obiektach DOM zwróconych z wielu funkcji
document
DOM. (tjquerySelectorAll
,form.elements
)
Załóżmy, że stworzyliśmy następujący obiekt, który ma pewne właściwości, których można się spodziewać w tablicy.
var anObject = {
foo: 'bar',
length: 'interesting',
'0': 'zero!',
'1': 'one!'
};
Następnie stworzymy tablicę.
var anArray = ['zero.', 'one.'];
Teraz zauważ, jak możemy w ten sam sposób sprawdzić zarówno obiekt, jak i tablicę.
console.log(anArray[0], anObject[0]); // outputs: zero. zero!
console.log(anArray[1], anObject[1]); // outputs: one. one!
console.log(anArray.length, anObject.length); // outputs: 2 interesting
console.log(anArray.foo, anObject.foo); // outputs: undefined bar
Ponieważ anArray
jest w rzeczywistości obiektem, podobnie jak anObject
, możemy nawet dodawać niestandardowe właściwości anArray
do anArray
Oświadczenie: tablice z własnymi właściwościami zwykle nie są zalecane, ponieważ mogą być mylące, ale mogą być przydatne w zaawansowanych przypadkach, w których potrzebujesz zoptymalizowanych funkcji tablicy. (tj. obiekty jQuery)
anArray.foo = 'it works!';
console.log(anArray.foo);
Możemy nawet zmienić anObject
na obiekt tablicowy, dodając length
.
anObject.length = 2;
Następnie możesz użyć pętli for
stylu C do iteracji po anObject
tak jakby to była tablica. Zobacz Iteracja macierzy
Zauważ, że anObject
jest tylko obiektem podobnym do tablicy . (znany również jako lista) To nie jest prawdziwa tablica. Jest to ważne, ponieważ funkcje takie jak push
i forEach
(lub dowolna funkcja wygody znaleziona w Array.prototype
) nie będą domyślnie działać na obiektach podobnych do tablicy.
Wiele DOM document
funkcji zwróci listę (tj querySelectorAll
, form.elements
), który jest podobny do tablicy, jak anObject
stworzyliśmy powyżej. Zobacz Konwertowanie obiektów podobnych do tablicy na tablice
console.log(typeof anArray == 'object', typeof anObject == 'object'); // outputs: true true
console.log(anArray instanceof Object, anObject instanceof Object); // outputs: true true
console.log(anArray instanceof Array, anObject instanceof Array); // outputs: true false
console.log(Array.isArray(anArray), Array.isArray(anObject)); // outputs: true false
Object.freeze
Object.freeze
sprawia, że obiekt jest niezmienny, zapobiegając dodawaniu nowych właściwości, usuwaniu istniejących właściwości oraz modyfikacji policzalności, konfigurowalności i możliwości zapisu istniejących właściwości. Zapobiega również zmianie wartości istniejących właściwości. Jednak nie działa rekurencyjnie, co oznacza, że obiekty potomne nie są automatycznie zamrażane i mogą ulec zmianie.
Operacje po zamrożeniu nie zakończą się niepowodzeniem, chyba że kod działa w trybie ścisłym. Jeśli kod jest w trybie ścisłym, o TypeError
zostanie wyrzucony.
var obj = {
foo: 'foo',
bar: [1, 2, 3],
baz: {
foo: 'nested-foo'
}
};
Object.freeze(obj);
// Cannot add new properties
obj.newProperty = true;
// Cannot modify existing values or their descriptors
obj.foo = 'not foo';
Object.defineProperty(obj, 'foo', {
writable: true
});
// Cannot delete existing properties
delete obj.foo;
// Nested objects are not frozen
obj.bar.push(4);
obj.baz.foo = 'new foo';
Object.seal
Object.seal
zapobiega dodawaniu lub usuwaniu właściwości z obiektu. Po zapieczętowaniu obiektu deskryptory właściwości nie mogą zostać przekonwertowane na inny typ. W przeciwieństwie do Object.freeze
umożliwia edycję właściwości.
Próby wykonania tych operacji na zapieczętowanym obiekcie zakończą się niepowodzeniem
var obj = { foo: 'foo', bar: function () { return 'bar'; } };
Object.seal(obj)
obj.newFoo = 'newFoo';
obj.bar = function () { return 'foo' };
obj.newFoo; // undefined
obj.bar(); // 'foo'
// Can't make foo an accessor property
Object.defineProperty(obj, 'foo', {
get: function () { return 'newFoo'; }
}); // TypeError
// But you can make it read only
Object.defineProperty(obj, 'foo', {
writable: false
}); // TypeError
obj.foo = 'newFoo';
obj.foo; // 'foo';
W trybie ścisłym operacje te TypeError
(function () {
'use strict';
var obj = { foo: 'foo' };
Object.seal(obj);
obj.newFoo = 'newFoo'; // TypeError
}());
Tworzenie obiektu iterowalnego
var myIterableObject = {};
// An Iterable object must define a method located at the Symbol.iterator key:
myIterableObject[Symbol.iterator] = function () {
// The iterator should return an Iterator object
return {
// The Iterator object must implement a method, next()
next: function () {
// next must itself return an IteratorResult object
if (!this.iterated) {
this.iterated = true;
// The IteratorResult object has two properties
return {
// whether the iteration is complete, and
done: false,
// the value of the current iteration
value: 'One'
};
}
return {
// When iteration is complete, just the done property is needed
done: true
};
},
iterated: false
};
};
for (var c of myIterableObject) {
console.log(c);
}
Wyjście konsoli
Jeden
Reszta / rozkładanie obiektów (...)
Object.assign({}, obj1, ..., objn);
obiektów to po prostu cukier składniowy dla Object.assign({}, obj1, ..., objn);
Odbywa się to za pomocą ...
operatora:
let obj = { a: 1 };
let obj2 = { ...obj, b: 2, c: 3 };
console.log(obj2); // { a: 1, b: 2, c: 3 };
Jako Object.assign
dokonuje płytkiego łączenia, a nie głębokiego łączenia.
let obj3 = { ...obj, b: { c: 2 } };
console.log(obj3); // { a: 1, b: { c: 2 } };
UWAGA : Ta specyfikacja jest obecnie na etapie 3
Deskryptory i nazwane właściwości
Właściwości są członkami obiektu. Każda nazwana właściwość jest parą (nazwa, deskryptor). Nazwa jest ciągiem, który umożliwia dostęp (za pomocą notacji kropkowej object.propertyName
lub object['propertyName']
notacji w nawiasach kwadratowych object['propertyName']
). Deskryptor jest zapisem pól definiujących zachowanie właściwości podczas uzyskiwania do niej dostępu (co dzieje się z właściwością i jaka jest wartość zwracana po uzyskaniu do niej dostępu). Ogólnie rzecz biorąc, właściwość kojarzy nazwę z zachowaniem (możemy myśleć o tym zachowaniu jak o czarnej skrzynce).
Istnieją dwa typy nazwanych właściwości:
- właściwość danych : nazwa właściwości jest powiązana z wartością.
- właściwość akcesorium : nazwa właściwości jest powiązana z jedną lub dwiema funkcjami akcesorium.
Demonstracja:
obj.propertyName1 = 5; //translates behind the scenes into
//either assigning 5 to the value field* if it is a data property
//or calling the set function with the parameter 5 if accessor property
//*actually whether an assignment would take place in the case of a data property
//also depends on the presence and value of the writable field - on that later on
Typ właściwości jest określony przez pola deskryptora, a właściwość nie może być obu typów.
Deskryptory danych -
- Wymagane pola:
value
lubwritable
albo oba - Pola opcjonalne:
configurable
,enumerable
Próba:
{
value: 10,
writable: true;
}
Deskryptory akcesoriów -
- Wymagane pola:
get
lubset
lub oba - Pola opcjonalne:
configurable
,enumerable
Próba:
{
get: function () {
return 10;
},
enumerable: true
}
znaczenie pól i ich wartości domyślne
configurable
, enumerable
i writable
: - Wszystkie te klucze mają domyślną wartość
false
. -
configurable
jesttrue
wtedy i tylko wtedy, gdy można zmienić typ tego deskryptora właściwości i jeśli właściwość można usunąć z odpowiedniego obiektu. -
enumerable
jesttrue
wtedy i tylko wtedy, gdy pojawia się podczas wyliczania właściwości dotyczących odpowiedniego obiektu tej nieruchomości. -
writable
jesttrue
wtedy i tylko wtedy, gdy wartość powiązaną z właściwością można zmienić za pomocą operatora przypisania.
get
i set
:
- Te klucze są domyślnie
undefined
. -
get
to funkcja, która służy jako getter dla właściwości lubundefined
jeśli nie ma gettera. Zwracana funkcja będzie używana jako wartość właściwości. -
set
jest funkcją, która służy jako obiekt ustawiający właściwość lubundefined
jeśli nie ma obiektu ustawiającego. Funkcja otrzyma jako jedyny argument nową wartość przypisaną do właściwości.
value
:
- Domyślnie ten klucz jest
undefined
. - Wartość powiązana z właściwością. Może to być dowolna poprawna wartość JavaScript (liczba, obiekt, funkcja itp.).
Przykład:
var obj = {propertyName1: 1}; //the pair is actually ('propertyName1', {value:1,
// writable:true,
// enumerable:true,
// configurable:true})
Object.defineProperty(obj, 'propertyName2', {get: function() {
console.log('this will be logged ' +
'every time propertyName2 is accessed to get its value');
},
set: function() {
console.log('and this will be logged ' +
'every time propertyName2\'s value is tried to be set')
//will be treated like it has enumerable:false, configurable:false
}});
//propertyName1 is the name of obj's data property
//and propertyName2 is the name of its accessor property
obj.propertyName1 = 3;
console.log(obj.propertyName1); //3
obj.propertyName2 = 3; //and this will be logged every time propertyName2's value is tried to be set
console.log(obj.propertyName2); //this will be logged every time propertyName2 is accessed to get its value
Object.getOwnPropertyDescriptor
Uzyskaj opis konkretnej właściwości w obiekcie.
var sampleObject = {
hello: 'world'
};
Object.getOwnPropertyDescriptor(sampleObject, 'hello');
// Object {value: "world", writable: true, enumerable: true, configurable: true}
Klonowanie obiektów
Gdy potrzebujesz pełnej kopii obiektu (tj. Właściwości obiektu i wartości wewnątrz tych właściwości itp.), Nazywa się to głębokim klonowaniem .
Jeśli obiekt może być zserializowany do JSON, możesz utworzyć jego głęboki klon za pomocą kombinacji JSON.parse
i JSON.stringify
:
var existing = { a: 1, b: { c: 2 } };
var copy = JSON.parse(JSON.stringify(existing));
existing.b.c = 3; // copy.b.c will not change
Zauważ, że JSON.stringify
skonwertuje obiekty Date
na reprezentacje ciągów w formacie ISO, ale JSON.parse
nie przekonwertuje ciągu z powrotem na Date
.
W JavaScript nie ma wbudowanej funkcji do tworzenia głębokich klonów i generalnie nie jest możliwe tworzenie głębokich klonów dla każdego obiektu z wielu powodów. Na przykład,
- obiekty mogą mieć właściwości niepoliczalne i ukryte, których nie można wykryć.
- obiekty pobierające i ustawiające obiekty nie mogą być kopiowane.
- obiekty mogą mieć strukturę cykliczną.
- właściwości funkcji mogą zależeć od stanu w ukrytym zakresie.
Zakładając, że masz „ładny” obiekt, którego właściwości zawierają tylko prymitywne wartości, daty, tablice lub inne „ładne” obiekty, to do tworzenia głębokich klonów można użyć następującej funkcji. Jest to funkcja rekurencyjna, która może wykrywać obiekty o cyklicznej strukturze i w takich przypadkach generuje błąd.
function deepClone(obj) {
function clone(obj, traversedObjects) {
var copy;
// primitive types
if(obj === null || typeof obj !== "object") {
return obj;
}
// detect cycles
for(var i = 0; i < traversedObjects.length; i++) {
if(traversedObjects[i] === obj) {
throw new Error("Cannot clone circular object.");
}
}
// dates
if(obj instanceof Date) {
copy = new Date();
copy.setTime(obj.getTime());
return copy;
}
// arrays
if(obj instanceof Array) {
copy = [];
for(var i = 0; i < obj.length; i++) {
copy.push(clone(obj[i], traversedObjects.concat(obj)));
}
return copy;
}
// simple objects
if(obj instanceof Object) {
copy = {};
for(var key in obj) {
if(obj.hasOwnProperty(key)) {
copy[key] = clone(obj[key], traversedObjects.concat(obj));
}
}
return copy;
}
throw new Error("Not a cloneable object.");
}
return clone(obj, []);
}
Object.assign
Metoda Object.assign () służy do kopiowania wartości wszystkich wyliczalnych właściwości własnych z jednego lub więcej obiektów źródłowych do obiektu docelowego. Zwróci obiekt docelowy.
Użyj go, aby przypisać wartości do istniejącego obiektu:
var user = {
firstName: "John"
};
Object.assign(user, {lastName: "Doe", age:39});
console.log(user); // Logs: {firstName: "John", lastName: "Doe", age: 39}
Lub utworzyć płytką kopię obiektu:
var obj = Object.assign({}, user);
console.log(obj); // Logs: {firstName: "John", lastName: "Doe", age: 39}
Lub scal wiele właściwości z wielu obiektów w jeden:
var obj1 = {
a: 1
};
var obj2 = {
b: 2
};
var obj3 = {
c: 3
};
var obj = Object.assign(obj1, obj2, obj3);
console.log(obj); // Logs: { a: 1, b: 2, c: 3 }
console.log(obj1); // Logs: { a: 1, b: 2, c: 3 }, target object itself is changed
Prymitywy zostaną opakowane, wartości puste i niezdefiniowane zostaną zignorowane:
var var_1 = 'abc';
var var_2 = true;
var var_3 = 10;
var var_4 = Symbol('foo');
var obj = Object.assign({}, var_1, null, var_2, undefined, var_3, var_4);
console.log(obj); // Logs: { "0": "a", "1": "b", "2": "c" }
Uwaga: tylko owijarki ciągów mogą mieć własne wyliczalne właściwości
Użyj go jako reduktora: (scala tablicę z obiektem)
return users.reduce((result, user) => Object.assign({}, {[user.id]: user})
Iteracja właściwości obiektu
Za pomocą tej pętli można uzyskać dostęp do każdej właściwości należącej do obiektu
for (var property in object) {
// always check if an object has a property
if (object.hasOwnProperty(property)) {
// do stuff
}
}
Należy uwzględnić dodatkowe sprawdzenie hasOwnProperty
ponieważ obiekt może mieć właściwości dziedziczone z podstawowej klasy obiektu. Niewykonanie tej kontroli może powodować błędy.
Możesz także użyć funkcji Object.keys
która zwraca tablicę zawierającą wszystkie właściwości obiektu, a następnie możesz przeszukiwać tę tablicę za Array.forEach
funkcji Array.map
lub Array.forEach
.
var obj = { 0: 'a', 1: 'b', 2: 'c' };
Object.keys(obj).map(function(key) {
console.log(key);
});
// outputs: 0, 1, 2
Pobieranie właściwości z obiektu
Charakterystyka właściwości:
Właściwości, które można pobrać z obiektu, mogą mieć następujące cechy:
- Wymienny
- Niewymienny
- posiadać
Podczas tworzenia właściwości za pomocą Object.defineProperty (ies) , możemy ustawić jego właściwości oprócz „własnych” . Właściwości, które są dostępne na poziomie bezpośrednim, a nie na poziomie prototypu ( __proto__
) obiektu, są nazywane własnymi właściwościami.
A właściwości, które są dodawane do obiektu bez użycia Object.defindProperty(ies)
, nie będą miały swoich wyliczalnych właściwości. Oznacza to, że należy to uznać za prawdziwe.
Cel wyliczalności:
Głównym celem nadania właściwościom wyliczalnych właściwości jest zapewnienie dostępności określonej właściwości podczas pobierania jej z obiektu za pomocą różnych metod programowych. Te różne metody zostaną omówione poniżej.
Metody pobierania właściwości:
Właściwości z obiektu można pobrać następującymi metodami:
for..in
pętliTa pętla jest bardzo przydatna przy pobieraniu wyliczalnych właściwości z obiektu. Dodatkowo ta pętla pobierze wyliczalne własne właściwości, a także dokona tego samego wyszukiwania, przechodząc przez łańcuch prototypów, dopóki nie zobaczy prototypu jako zerowego.
//Ex 1 : Simple data var x = { a : 10 , b : 3} , props = []; for(prop in x){ props.push(prop); } console.log(props); //["a","b"] //Ex 2 : Data with enumerable properties in prototype chain var x = { a : 10 , __proto__ : { b : 10 }} , props = []; for(prop in x){ props.push(prop); } console.log(props); //["a","b"] //Ex 3 : Data with non enumerable properties var x = { a : 10 } , props = []; Object.defineProperty(x, "b", {value : 5, enumerable : false}); for(prop in x){ props.push(prop); } console.log(props); //["a"]
Ta funkcja została zaprezentowana jako część EcmaScript 5. Służy ona do pobierania wyliczalnych własnych właściwości z obiektu. Przed jego wydaniem ludzie używali do pobierania własnych właściwości z obiektu przez połączenie funkcji
for..in
iObject.prototype.hasOwnProperty()
.//Ex 1 : Simple data var x = { a : 10 , b : 3} , props; props = Object.keys(x); console.log(props); //["a","b"] //Ex 2 : Data with enumerable properties in prototype chain var x = { a : 10 , __proto__ : { b : 10 }} , props; props = Object.keys(x); console.log(props); //["a"] //Ex 3 : Data with non enumerable properties var x = { a : 10 } , props; Object.defineProperty(x, "b", {value : 5, enumerable : false}); props = Object.keys(x); console.log(props); //["a"]
Ta funkcja pobierze z obiektu zarówno własne, jak i niepoliczalne, własne właściwości. Został również wydany jako część EcmaScript 5.
//Ex 1 : Simple data var x = { a : 10 , b : 3} , props; props = Object.getOwnPropertyNames(x); console.log(props); //["a","b"] //Ex 2 : Data with enumerable properties in prototype chain var x = { a : 10 , __proto__ : { b : 10 }} , props; props = Object.getOwnPropertyNames(x); console.log(props); //["a"] //Ex 3 : Data with non enumerable properties var x = { a : 10 } , props; Object.defineProperty(x, "b", {value : 5, enumerable : false}); props = Object.getOwnPropertyNames(x); console.log(props); //["a", "b"]
Różne :
Technika pobierania wszystkich właściwości (własnych, policzalnych, niepoliczalnych, wszystkich na poziomie prototypu) z obiektu jest podana poniżej,
function getAllProperties(obj, props = []){
return obj == null ? props :
getAllProperties(Object.getPrototypeOf(obj),
props.concat(Object.getOwnPropertyNames(obj)));
}
var x = {a:10, __proto__ : { b : 5, c : 15 }};
//adding a non enumerable property to first level prototype
Object.defineProperty(x.__proto__, "d", {value : 20, enumerable : false});
console.log(getAllProperties(x)); ["a", "b", "c", "d", "...other default core props..."]
Będzie to obsługiwane przez przeglądarki obsługujące EcmaScript 5.
Konwertuj wartości obiektu na tablicę
Biorąc pod uwagę ten obiekt:
var obj = {
a: "hello",
b: "this is",
c: "javascript!",
};
Możesz przekonwertować jego wartości na tablicę, wykonując:
var array = Object.keys(obj)
.map(function(key) {
return obj[key];
});
console.log(array); // ["hello", "this is", "javascript!"]
Iteracja po wpisach obiektów - Object.entries ()
Proponowana Object.entries()
zwraca tablicę par klucz / wartość dla danego obiektu. Nie zwraca iteratora takiego jak Array.prototype.entries()
, ale tablicę zwracaną przez Object.entries()
można iterować niezależnie.
const obj = {
one: 1,
two: 2,
three: 3
};
Object.entries(obj);
Prowadzi do:
[
["one", 1],
["two", 2],
["three", 3]
]
Jest to przydatny sposób na iterację par klucz / wartość obiektu:
for(const [key, value] of Object.entries(obj)) {
console.log(key); // "one", "two" and "three"
console.log(value); // 1, 2 and 3
}
Object.values ()
Metoda Object.values()
zwraca tablicę własnych wyliczalnych wartości właściwości danego obiektu, w tej samej kolejności, jaką zapewnia pętla for ... in (różnica polega na tym, że pętla for wylicza właściwości w łańcuchu prototypów także).
var obj = { 0: 'a', 1: 'b', 2: 'c' };
console.log(Object.values(obj)); // ['a', 'b', 'c']
Uwaga:
Aby uzyskać wsparcie przeglądarki, zapoznaj się z tym linkiem