Domů O mně Služby Portfolio Učím Blog Kontakt
← Zpět na učím

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]
  • delete operátor - odstraní vlastnost
  • in operátor - zkontroluje existenci vlastnosti
  • hasOwnProperty - 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 = newValue př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.key odstraní vlastnost z objektu
  • Vlastnost už neexistuje (ne jen undefined)
  • delete vrací true pokud ú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í true pokud klíč existuje (i když hodnota je undefined)
  • obj.hasOwnProperty('key') - vrací true jen 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 - readonly pro neměnné vlastnosti
  • Index signatures - [key: string]: any pro 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 objfalse (vlastnost už neexistuje)
  • 'age' in objtrue (vlastnost existuje, i když hodnota je undefined)
  • in operá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 →

Připraveni začít?

Zaregistrujte se a získejte přístup ke všem dílům tohoto seriálu

Kontaktujte mě

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


Struktura lekcí (souborový strom)

06. Typescript specifika
  • v přípravě
08. Moduly tridy
  • v přípravě
09. React zaklady
  • v přípravě
10. React hooks
  • v přípravě
12. Nextjs server
  • v přípravě
13. Databaze auth
  • v přípravě
14. Nextjs pokrocile
  • v přípravě