05.2 Vlastnosti
Výuka
Proč vlastnosti?
Vlastnosti (properties) jsou pojmenované hodnoty uvnitř objektu. Umožňují ti ukládat a organizovat související data pod jedním „střechou".
Proč to potřebujeme?
- Přístup k datům - Číst hodnoty podle názvu klíče
- Úprava dat - Měnit hodnoty vlastností
- Přidávání/odstranění - Dynamicky měnit strukturu objektu
- Kontrola existence - Zjistit, zda vlastnost existuje
Představ si to jako: Karty v kartotéce. Každá karta (vlastnost) má název (klíč) a obsah (hodnota). Můžeš karty číst, upravovat, přidávat nebo odstraňovat.
Jak to funguje?
Vlastnosti objektu:
1. Přístup: obj.key nebo obj['key']
2. Úprava: obj.key = newValue
3. Přidání: obj.newKey = value (pokud klíč neexistuje, vytvoří se)
4. Odstranění: delete obj.key
5. Kontrola: 'key' in obj nebo obj.hasOwnProperty('key')
Klíčové koncepty
- Dot notation - přístup přes tečku:
obj.name - Bracket notation - přístup přes závorky:
obj['name'] - Dynamické klíče - klíč ze proměnné:
obj[variableName] deleteoperátor - odstraní vlastnostinoperátor - zkontroluje existenci vlastnostihasOwnProperty- zkontroluje vlastní vlastnost (ne zděděnou)
JavaScript
Příklad 1: Čtení vlastností (dot a bracket notation)
const person = {
name: 'Alice',
age: 25,
city: 'Praha'
};
// Dot notation (tečková notace)
console.log(person.name);
// → Alice
console.log(person.age);
// → 25
// Bracket notation (závorková notace)
console.log(person['city']);
// → Praha
// Neexistující vlastnost vrací undefined
console.log(person.country);
// → undefined
Co se stalo?
- Dot notation -
obj.key- preferovaný způsob - Bracket notation -
obj['key']- pro dynamické klíče - Neexistující vlastnost vrací
undefined
Příklad 2: Úprava a přidávání vlastností
const car = {
brand: 'Toyota',
model: 'Camry',
year: 2020
};
// Úprava existující vlastnosti
car.year = 2021;
console.log(car.year);
// → 2021
// Přidání nové vlastnosti (dot notation)
car.color = 'red';
console.log(car);
// → { brand: 'Toyota', model: 'Camry', year: 2021, color: 'red' }
// Přidání nové vlastnosti (bracket notation)
car['owner'] = 'Bob';
console.log(car.owner);
// → Bob
Co se stalo?
- Úprava:
obj.key = newValuepřepíše hodnotu - Přidání: Pokud klíč neexistuje, vytvoří se nová vlastnost
- Můžeš použít dot nebo bracket notation
Příklad 3: Dynamické klíče (bracket notation)
const user = {
name: 'Charlie',
age: 30,
email: 'charlie@example.com'
};
// Dynamický přístup - klíč ze proměnné
const field = 'name';
console.log(user[field]);
// → Charlie
// Můžeš měnit proměnnou
const field2 = 'age';
console.log(user[field2]);
// → 30
// Praktické použití - iterace
const fields = ['name', 'age', 'email'];
fields.forEach(key => {
console.log(`${key}: ${user[key]}`);
});
// → name: Charlie
// → age: 30
// → email: charlie@example.com
// Klíč s mezerou nebo speciálními znaky
const obj = {
'full name': 'David Johnson',
'user-id': 123
};
console.log(obj['full name']);
// → David Johnson
console.log(obj['user-id']);
// → 123
// Dot notation by nefungovalo:
// console.log(obj.full name); // ❌ Syntax Error
Co se stalo?
- Bracket notation umožňuje dynamické klíče (hodnota v proměnné)
- Užitečná pro klíče s mezerami nebo speciálními znaky
- Můžeš použít výrazy:
obj[getKey()],obj['user' + Id]
Příklad 4: Odstranění vlastnosti (delete operátor)
const product = {
name: 'Laptop',
price: 25000,
stock: 10,
discount: 0.1
};
console.log(product);
// → { name: 'Laptop', price: 25000, stock: 10, discount: 0.1 }
// Odstraň vlastnost
delete product.discount;
console.log(product);
// → { name: 'Laptop', price: 25000, stock: 10 }
// Kontrola - vlastnost už neexistuje
console.log(product.discount);
// → undefined
// delete vrací true/false
const removed = delete product.stock;
console.log(removed);
// → true
console.log(product);
// → { name: 'Laptop', price: 25000 }
Co se stalo?
delete obj.keyodstraní vlastnost z objektu- Vlastnost už neexistuje (ne jen
undefined) deletevracítruepokud úspěšné
Příklad 5: Kontrola existence vlastnosti
const user = {
name: 'Eve',
age: 28,
email: undefined // Schválně undefined
};
// in operátor - kontroluje existenci klíče
console.log('name' in user);
// → true
console.log('age' in user);
// → true
console.log('phone' in user);
// → false
// POZOR: 'in' vrací true i pro undefined
console.log('email' in user);
// → true (klíč existuje, i když hodnota je undefined)
// hasOwnProperty - kontroluje vlastní vlastnost (ne zděděnou)
console.log(user.hasOwnProperty('name'));
// → true
console.log(user.hasOwnProperty('toString'));
// → false (toString je zděděná metoda z prototypu)
// Porovnání s undefined (NEBEZPEČNÉ)
console.log(user.phone === undefined);
// → true (ale phone neexistuje!)
console.log(user.email === undefined);
// → true (email existuje, ale hodnota je undefined)
// Lepší: použij 'in' operátor
if ('phone' in user) {
console.log('Phone:', user.phone);
} else {
console.log('Phone neexistuje');
}
// → Phone neexistuje
Co se stalo?
'key' in obj- vracítruepokud klíč existuje (i když hodnota jeundefined)obj.hasOwnProperty('key')- vracítruejen pro vlastní vlastnosti (ne zděděné)obj.key === undefined- NEBEZPEČNÉ - nerozlišuje neexistující vs. undefined hodnotu
Příklad 6: Computed property names (vypočítané klíče)
// Dynamické klíče při vytváření objektu
const prefix = 'user';
const id = 123;
const user = {
[prefix + 'Id']: id, // → userId: 123
[prefix + 'Name']: 'Frank', // → userName: 'Frank'
['is' + 'Active']: true // → isActive: true
};
console.log(user);
// → { userId: 123, userName: 'Frank', isActive: true }
// Praktický příklad - vytvoření objektu z pole
const fields = ['name', 'age', 'city'];
const values = ['George', 35, 'Brno'];
const person = {};
fields.forEach((field, index) => {
person[field] = values[index];
});
console.log(person);
// → { name: 'George', age: 35, city: 'Brno' }
// Nebo s reduce
const person2 = fields.reduce((obj, field, index) => {
obj[field] = values[index];
return obj;
}, {});
console.log(person2);
// → { name: 'George', age: 35, city: 'Brno' }
Co se stalo?
- Computed property names:
{ [výraz]: hodnota } - Klíč je vyhodnocen jako výraz
- Užitečné pro dynamické vytváření objektů
TypeScript
TypeScript přidává typovou kontrolu vlastností.
Stejné příklady s typy
// Interface definuje vlastnosti
interface Person {
name: string;
age: number;
city: string;
}
const person: Person = {
name: 'Alice',
age: 25,
city: 'Praha'
};
// Přístup k vlastnostem - typová kontrola
const userName: string = person.name; // ✅ OK
// const userName: number = person.name; // ❌ Error: Type 'string' is not assignable to type 'number'
// Úprava vlastnosti - musí odpovídat typu
person.age = 26; // ✅ OK
// person.age = 'twenty-six'; // ❌ Error: Type 'string' is not assignable to type 'number'
// Přidání nové vlastnosti - ERROR v TypeScript
// person.phone = '123456'; // ❌ Error: Property 'phone' does not exist on type 'Person'
// Řešení 1: Rozšíř interface
interface PersonWithPhone extends Person {
phone?: string;
}
const person2: PersonWithPhone = {
name: 'Bob',
age: 30,
city: 'Brno',
phone: '123456'
};
// Řešení 2: Index signature (flexibilní objekt)
interface FlexiblePerson {
name: string;
age: number;
[key: string]: any; // Libovolné další vlastnosti
}
const person3: FlexiblePerson = {
name: 'Charlie',
age: 35
};
person3.email = 'charlie@example.com'; // ✅ OK
person3.phone = '123456'; // ✅ OK
// Optional properties
interface User {
name: string;
age: number;
email?: string; // Volitelná
}
const user1: User = {
name: 'David',
age: 40
// email není povinný
};
const user2: User = {
name: 'Eve',
age: 28,
email: 'eve@example.com'
};
// Readonly properties
interface Product {
readonly id: number;
name: string;
price: number;
}
const product: Product = {
id: 1,
name: 'Laptop',
price: 25000
};
product.price = 24000; // ✅ OK
// product.id = 2; // ❌ Error: Cannot assign to 'id' because it is a read-only property
// Dynamic keys with keyof
type PersonKey = keyof Person; // 'name' | 'age' | 'city'
function getProperty(obj: Person, key: PersonKey): string | number {
return obj[key];
}
const value = getProperty(person, 'name'); // ✅ OK
// const value2 = getProperty(person, 'phone'); // ❌ Error: Argument of type '"phone"' is not assignable to parameter of type 'PersonKey'
TypeScript přidává:
- ✅ Typovou kontrolu vlastností - nemůžeš přiřadit špatný typ
- ✅ Prevenci přidávání neznámých vlastností - chráněná struktura
- ✅ Optional properties -
?pro volitelné vlastnosti - ✅ Readonly properties -
readonlypro neměnné vlastnosti - ✅ Index signatures -
[key: string]: anypro flexibilní objekty
Rozdíl JS vs TS
JavaScript:
- Můžeš přidat/odebrat vlastnosti kdykoliv
- Žádná typová kontrola hodnot
- Flexibilnější, ale nebezpečnější
TypeScript:
- Struktura objektu je definovaná (interface/type)
- TypeScript zkontroluje typy vlastností
- Nemůžeš přidat neznámé vlastnosti (bez index signature)
- Bezpečnější, prevence chyb
// JavaScript - projde
const person = { name: 'Alice', age: 25 };
person.city = 'Praha'; // OK
person.age = 'twenty-five'; // OK (ale problematické)
// TypeScript - kontrola
interface Person {
name: string;
age: number;
}
const person: Person = { name: 'Alice', age: 25 };
// person.city = 'Praha'; // ❌ Error: Property 'city' does not exist
// person.age = 'twenty-five'; // ❌ Error: Type 'string' is not assignable to type 'number'
Tip
💡 Používej 'in' operátor pro kontrolu existence:
// ❌ Nebezpečné - nerozlišuje neexistující vs. undefined
if (user.email === undefined) {
// email může neexistovat NEBO být undefined
}
// ✅ Spolehlivé - kontroluje existenci klíče
if ('email' in user) {
// email existuje (i když může být undefined)
}
💡 Dot notation preferuj, bracket pro dynamické klíče:
// ✅ Dot notation - čitelnější
const name = person.name;
// ✅ Bracket notation - dynamické klíče
const field = 'name';
const value = person[field];
// ✅ Bracket notation - klíče s mezerami
const fullName = person['full name'];
💡 Delete vs nastavení na undefined:
const obj = { a: 1, b: 2 };
// ❌ Vlastnost existuje, hodnota je undefined
obj.a = undefined;
console.log('a' in obj); // → true
// ✅ Vlastnost neexistuje
delete obj.a;
console.log('a' in obj); // → false
Kvíz
Co vypíše tento kód?
const obj = {
name: 'Alice',
age: undefined
};
delete obj.name;
console.log('name' in obj);
console.log('age' in obj);
❌ - name byla odstraněna pomocí delete
❌ - age stále existuje (hodnota undefined neznamená, že klíč neexistuje)
✅ - - delete obj.name odstraní vlastnost name z objektu
'name' in obj→false(vlastnost už neexistuje)'age' in obj→true(vlastnost existuje, i když hodnota jeundefined)inoperátor kontroluje EXISTENCI klíče, ne hodnotu!
❌ - Obrácené hodnoty
Důležité: delete odstraní vlastnost (klíč i hodnota). Nastavení na undefined vlastnost NEODSTRANÍ, jen změní hodnotu!
Důležité: delete odstraní vlastnost (klíč i hodnota). Nastavení na undefined vlastnost NEODSTRANÍ, jen změní hodnotu!
🎯 Závěrečný projekt
Po dokončení všech 8 dílů vytvoříte jednoduchou Todо aplikaci v čistém JavaScriptu. Naučíte se, jak aplikovat vše, co jste se naučili, na reálný projekt.
Zobrazit podrobnosti projektu →Informace o seriálu
Obtížnost
Délka
Cca 480 minut
Počet videí
8 videí + projekty
Certifikát
Po dokončení obdržíte certifikát
Lekce v této sekci
- 05.1 Vytvoření objektu
- 05.2 Vlastnosti
- 05.3 Metody objektu
- 05.4 This keyword
- 05.5 Destructuring objektů
- 05.6 Spread u objektů
- 05.7 Optional chaining
- 05.8 Nullish coalescing
- 05.9 Object.keys/values/entries
- 05.10 Computed properties
- 05.11 Getters a setters
- 05.12 Object.freeze/seal
Struktura lekcí (souborový strom)
- 1.1 Úvod do JavaScriptu a TypeScriptu
- 1.2 Nastavení prostředí
- 1.3 První program
- 1.4 Proměnné: var, let, const
- 1.5 Datové typy - přehled
- 1.6 String (řetězce)
- 1.7 Number (čísla)
- 1.8 Boolean (pravda/nepravda)
- 1.9 Null a Undefined
- 1.10 Type Inference vs Annotations
- 1.11 Aritmetické operátory
- 1.12 Porovnávací operátory
- 1.13 Logické operátory
- 1.14 Komentáře
- 1.15 Console metody
- 03.01 Deklarace funkce
- 03.02 Function Expression
- 03.03 Arrow Functions
- 03.04 Parametry a argumenty
- 03.05 Return hodnoty
- 03.06 Výchozí parametry
- 03.07 Rest parametry
- 03.08 Co je Scope
- 03.09 Lexikální Scope
- 03.10 Řetězec Scope
- 03.11 Globální Scope
- 03.12 Životní Cyklus Proměnných
- 03.13 Omezení Scope
- 03.14 Použití Closures
- 03.15 Callback funkce
- 03.16 Higher-order Functions
- 03.17 IIFE
- 03.18 Void funkce
- 03.19 Rekurze
- v přípravě
- v přípravě
- v přípravě
- v přípravě
- 01 — Co je Next.js
- 02 — Vytvoření projektu
- 03 — Struktura projektu (app/)
- 04 — Page komponenty (page.js / page.tsx)
- 05 — Layout komponenty (layout.js / layout.tsx)
- 06 — File-based routing
- 07 — Dynamické routy ([id]/page.js)
- 08 — Link komponenta (navigace)
- 09 — Image komponenta (next/image)
- 10 — Metadata (title, description, Open Graph)
- 11 — Loading UI (loading.js / loading.tsx)
- 12 — Error handling (error.js / error.tsx)
- 13 — Not Found (not-found.js / not-found.tsx)
- v přípravě
- v přípravě
- v přípravě