Հայերեն
English
Русский
Lesson 15: ES6 Features: Arrow Functions, Classes, and Modules
Introduction to ES6 (ECMAScript 2015)
Overview of ES6
ECMAScript 6, also known as ES6 and officially as ECMAScript 2015, represents a significant update to JavaScript, marking the first major update to the language since ES5 was standardized in 2009. ES6 introduced several new features and syntax improvements that modernized JavaScript, making it more powerful, efficient, and easier to work with, especially for developing complex applications. This update was pivotal in aligning JavaScript more closely with other high-level programming languages, enhancing its capabilities and robustness for both client-side and server-side development.
Historical Context and Significance:
- Closing the Gap: Prior to ES6, JavaScript lacked several constructs that were common in other languages, which sometimes made the language feel less equipped for certain types of heavy-duty applications. ES6 addressed many of these deficiencies.
- Standardization: ES6 brought about a new era of JavaScript development with an emphasis on future-proofing and standardized features that ensure consistency across different JavaScript engines.
- Developer Experience: By introducing a bevy of new features, ES6 made code simpler and more expressive, significantly improving the developer experience.
Key Features Overview
ES6 introduced a suite of new features that have since become fundamental to modern JavaScript programming. Here’s an overview of some of the most impactful features:
Arrow Functions:
- Provides a more concise syntax for writing functions.
- Does not have its own
this, arguments, super, or new.target bindings, which makes them ideal for situations where you want to retain the lexical this value from the surrounding code.
const sum = (a, b) => a + b;
Classes:
- JavaScript classes introduced in ES6 are primarily syntactical sugar over JavaScript's existing prototype-based inheritance and offer a much cleaner and clearer syntax to create objects and deal with inheritance.
class Rectangle {
constructor(height, width) {
this.height = height;
this.width = width;
}
}
Modules:
- ES6 modules include support for exporting and importing functions, objects, and classes, which greatly enhances code reusability and maintainability.
// file1.js
export const pi = 3.14159;
// file2.js
import { pi } from './file1.js';
console.log(pi); // 3.14159
Template Literals:
- Template literals provide an easy way to create multiline strings and perform string interpolation, facilitating more readable code.
const user = 'Jane';
console.log(`Hi ${user}, welcome back!`);
Destructuring:
- Destructuring allows binding using pattern matching, with support for matching arrays and objects. Destructuring is useful for extracting multiple properties from an object or array simultaneously.
const [x, y] = [1, 2];
const {a, b} = {a:1, b:2};
Spread/Rest Operators:
- The spread operator allows an iterable such as an array to be expanded in places where zero or more arguments (for function calls) or elements (for array literals) are expected. The rest operator does the opposite, collecting multiple elements and condensing them into a single element.
const nums = [1, 2, 3];
const numsCopy = [...nums]; // Spread as copying an array
function sum(...args) { // Rest as collecting function arguments
return args.reduce((total, n) => total + n, 0);
}
Each of these features introduced with ES6 has been carefully designed to address specific development needs, contributing to JavaScript’s evolution as a mature and comprehensive programming language suitable for a wide range of applications. The lesson will delve deeper into these features, illustrating how they can be effectively used in modern web development.
Arrow Functions in JavaScript
Syntax of Arrow Functions
Arrow functions introduce a new and more concise syntax for writing functions in JavaScript, which not only simplifies the function declaration but also changes how this binds within the function.
Basic Syntax:
A simple arrow function with explicit parameters can be defined as follows:
const add = (a, b) => a + b;
This function takes two parameters and returns their sum. Notice the absence of the function keyword and the use of =>.
If the function has only one parameter, the parentheses around the parameter can be omitted:
const square = x => x * x;
For functions with no parameters, or multiple statements, you must use parentheses and curly braces, respectively:
const greet = () => console.log("Hello World!");
const multiply = (a, b) => {
let result = a * b;
return result;
};
this Binding:
Unlike traditional functions, arrow functions do not have their own this context. Instead, this is lexically inherited from the outer function where the arrow function is defined. This means that inside an arrow function, this remains the same throughout the lifecycle of the function and is always bound to the this value of the closest non-arrow parent function.
Benefits and Usage
Lexical Scoping of this:
The main advantage of arrow functions is their handling of this. In traditional function expressions, this can change depending on the context in which the function is called. Arrow functions fix this based on the context where the function is created, not where it is invoked. This makes arrow functions particularly useful in scenarios where functions are used as arguments, such as event handlers or callbacks.
Concise Syntax:
Arrow functions provide a more succinct way to write functions. This shorter syntax is helpful not only for simple functions but also makes code look cleaner and more readable, especially when working with higher-order functions like map, filter, or reduce which commonly take callback functions as arguments.
Practical Exercise: Refactoring Traditional Functions
Objective:
Refactor a series of traditional functions into arrow functions, highlighting how this can simplify the codebase and improve readability.
Before Refactoring:
A traditional function to filter even numbers from an array:
function filterEvens(numbers) {
return numbers.filter(function(number) {
return number % 2 === 0;
});
}
A traditional function to compute the total of an array of numbers:
function computeTotal(numbers) {
return numbers.reduce(function(total, number) {
return total + number;
}, 0);
}
After Refactoring:
Refactored to use an arrow function:
const filterEvens = numbers => numbers.filter(number => number % 2 === 0);
Refactored to use an arrow function:
const computeTotal = numbers => numbers.reduce((total, number) => total + number, 0);
Exercise Tasks:
- Guide students through converting these and potentially more complex functions.
- Discuss how the refactor changes the way
this behaves if these functions were methods of an object and how it might affect the method's interaction with the object's properties.
- Encourage students to explore using arrow functions with other array methods or as event handlers where lexical
this would be beneficial.
Through these exercises, students will not only learn to write cleaner, more modern JavaScript but also understand some subtle nuances of function execution context, particularly how this binding can simplify development in common programming patterns.
Classes in JavaScript
Introduction to Classes
Classes in JavaScript, introduced in ES6, provide a syntactical sugar over the existing prototype-based inheritance and offer a clearer and more elegant syntax for creating objects and dealing with inheritance. Before ES6, inheritance in JavaScript was accomplished through prototype chains, which could be verbose and not as intuitive, especially for developers coming from class-based languages like Java or C#.
Syntax and Structure:
- Class Declaration: To declare a class, you use the
class keyword followed by the class name.
- Constructor: The
constructor method is a special method for creating and initializing objects created with the class. There can only be one constructor method in a class.
- Methods: Classes can contain multiple methods. Unlike function expressions, methods defined in a class are not hoisted, so they cannot be called before they are defined in the class body.
class Rectangle {
constructor(height, width) {
this.height = height;
this.width = width;
}
area() {
return this.height * this.width;
}
}
Creating Classes and Inheritance
Defining a Class:
Using the class keyword simplifies the definition of complex objects with their own prototypes.
Inheritance:
Inheritance is a way to create a class as a specialized version of one or more classes. JavaScript implements inheritance using the extends keyword.
extends Keyword: The extends keyword is used in class declarations or class expressions to create a class as a child of another class.
Example of Inheritance:
class Person {
constructor(name) {
this.name = name;
}
greet() {
return `Hello, my name is ${this.name}`;
}
}
class Student extends Person {
constructor(name, level) {
super(name); // Call the parent class constructor
this.level = level;
}
study() {
return `${this.name} is studying at level ${this.level}`;
}
}
Practical Examples
Classes are incredibly useful for modeling real-world entities and relationships. Here’s a practical example involving a Person class and a Student class that inherits from it:
let student = new Student("John", 12);
console.log(student.greet()); // "Hello, my name is John"
console.log(student.study()); // "John is studying at level 12"
This example illustrates how Student inherits functionality from Person while adding its own unique behavior.
Hands-On Exercise: Creating Classes
Objective:
Students will create their own classes encapsulating functionality for a simple application. Example applications include a digital clock or a basic inventory system.
Digital Clock Example:
- Goal: Create a
Clock class that maintains the current time and updates it every second.
- Implementation:
class Clock {
constructor() {
this.currentTime = new Date();
this.updateTime();
}
updateTime() {
setInterval(() => {
this.currentTime = new Date(); // Update time every second
console.log(this.currentTime.toLocaleTimeString()); // Display time
}, 1000);
}
}
const myClock = new Clock(); // Create a new clock instance
Basic Inventory System:
- Goal: Develop an
Inventory class that allows adding and tracking items.
- Implementation:
class Inventory {
constructor() {
this.items = [];
}
addItem(item) {
this.items.push(item);
console.log(`Added ${item} to inventory`);
}
listItems() {
console.log("Inventory Items:");
this.items.forEach(item => console.log(item));
}
}
const myInventory = new Inventory();
myInventory.addItem("Backpack");
myInventory.addItem("Notebook");
myInventory.listItems();
These exercises provide a hands-on way for students to apply their knowledge of JavaScript classes, exploring both inheritance and the encapsulation of functionality within class structures. The goal is to illustrate how classes can be used to structure applications more effectively, enhancing readability and maintainability.
Modules in JavaScript
Why Use Modules?
Modules are an essential aspect of building scalable and maintainable applications. By dividing a program into discrete chunks of functionality, modules offer several advantages:
Maintainability: Smaller, well-defined modules are easier to understand, debug, and update compared to large monolithic code bases. Each module has a clear focus and can be maintained independently of others.
Reusability: Modules allow you to reuse code across different parts of an application or even between different projects. For example, a module handling date and time operations can be reused wherever such functionality is required without duplication.
Namespace Management: Modules help in avoiding global namespace pollution. They encapsulate their variables and functions, exposing only what is explicitly exported. This reduces the risk of naming conflicts across your codebase.
Dependency Management: With modules, it's clear which files depend on which other files, making the structure of projects clearer and helping to ensure that scripts are loaded in the correct order.
Exporting and Importing Modules
Exporting a Module:
Named Exports: You can export multiple objects, functions, or primitives from a module using named exports. Each export can be referenced by its own name upon import.
// utils.js
export const add = (a, b) => a + b;
export const multiply = (a, b) => a * b;
Default Export: Each module can optionally export one default export, which is considered the main "value" that the module provides.
// greeting.js
export default function greet(name) {
return `Hello, ${name}!`;
}
Importing a Module:
Importing Named Exports: You can import specific parts of a module by using the named exports.
// app.js
import { add, multiply } from './utils.js';
console.log(add(2, 3)); // Output: 5
console.log(multiply(2, 3)); // Output: 6
Importing Default Exports: Default exports are imported without the use of brackets.
// main.js
import greet from './greeting.js';
console.log(greet('Alice')); // Output: Hello, Alice!
Hands-On Activity: Modularizing a Small Application
Objective: Students will modularize a simple application into distinct components. Let's assume a basic application that displays user data.
Structure:
Data Module: Holds the user data.
Logic Module: Contains business logic, like a function to find a user by name.
Presentation Module: Handles displaying information in the console or to the DOM.
Main Application File:
Task:
- Each student will create these modules and link them together using ES6 module syntax.
- Optionally, students could add more functionality, like updating or deleting user data, to practice modularizing complex functionalities.
This activity provides a practical example of how ES6 modules can be used to organize code in a real-world application, emphasizing clean separation of concerns and improving code manageability.
Additional ES6 Features
Template Literals
Template literals enhance the creation of complex strings by allowing for embedded expressions and multi-line strings without the need for concatenation operators (+). They are enclosed by backticks (``) rather than the traditional single or double quotes.
Features of Template Literals:
- Multi-line Strings: Easily create strings that span multiple lines without needing to include newline characters manually.
- Expression Interpolation: Insert expressions directly within the string using
${expression} syntax, which gets evaluated and converted to a string.
Example Usage:
const name = "Alice";
const age = 25;
const greeting = `Hello, my name is ${name} and I am ${age} years old.`;
console.log(greeting);
// Output: Hello, my name is Alice and I am 25 years old.
Destructuring
Destructuring allows you to unpack values from arrays or properties from objects into distinct variables.
Array Destructuring:
- Extract elements from an array and assign them to variables.
const numbers = [1, 2, 3];
const [one, two, three] = numbers;
console.log(one, two, three); // Output: 1 2 3
Object Destructuring:
- Extract properties from an object.
const user = { name: "John", age: 30 };
const { name, age } = user;
console.log(name, age); // Output: John 30
Spread and Rest Operators
Spread Operator (...):
- Arrays: Spread elements of an array into a new array.
const parts = ['shoulders', 'knees'];
const bodyParts = ['head', ...parts, 'toes'];
console.log(bodyParts); // Output: ["head", "shoulders", "knees", "toes"]
- Objects: Copy properties from one object to another.
const item = { name: 'Coffee', price: 2 };
const updatedItem = { ...item, price: 3 };
console.log(updatedItem); // Output: { name: 'Coffee', price: 3 }
Rest Parameters:
- Represent an indefinite number of arguments as an array.
function sum(...numbers) {
return numbers.reduce((total, n) => total + n, 0);
}
console.log(sum(1, 2, 3)); // Output: 6
Practical Exercises
Objective: Students apply template literals, destructuring, and spread/rest operators to simplify and enhance the functionality of JavaScript snippets.
Example Exercise: Improve a function that handles an object representing a new user’s data.
Provided Snippet:
function createUser(displayName, email, id) {
return {
displayName: displayName,
email: email,
id: id
};
}
Improved Version Using ES6 Features:
- Refactor with Destructuring and Object Property Shorthand:
function createUser(user) {
const { displayName, email, id } = user;
return { displayName, email, id };
}
// Usage
const userData = { displayName: "Alice", email: "alice@example.com", id: 1 };
console.log(createUser(userData));
- Incorporate Template Literals for Output:
function displayUserInfo(user) {
const info = `User: ${user.displayName}, Email: ${user.email}`;
console.log(info);
}
displayUserInfo(userData);
Task: Students are to take a code snippet that manually concatenates strings and uses index-based access for arrays and objects, and refactor it using the discussed ES6 features. This will demonstrate the power and simplicity that these features bring to JavaScript, making code more readable and maintainable.
Դաս 15. ES6-ի առանձնահատկությունները. սլաքի գործառույթներ, դասեր և մոդուլներ
Ներածություն ES6-ին (ECMAScript 2015)
ES6-ի ակնարկ
ECMAScript 6-ը, որը նաև հայտնի է որպես ES6 և պաշտոնապես որպես ECMAScript 2015, ներկայացնում է JavaScript-ի զգալի թարմացում՝ նշելով լեզվի առաջին հիմնական թարմացումը 2009 թվականին ES5-ի ստանդարտացումից ի վեր: ES6-ը ներկայացրել է մի քանի նոր հնարավորություններ և շարահյուսական բարելավումներ, որոնք արդիականացրել են JavaScript-ը՝ դարձնելով այն ավելին: հզոր, արդյունավետ և ավելի հեշտ է աշխատել, հատկապես բարդ հավելվածներ մշակելու համար: Այս թարմացումը առանցքային նշանակություն ունեցավ JavaScript-ն ավելի սերտորեն համապատասխանեցնելու այլ բարձր մակարդակի ծրագրավորման լեզուներին՝ բարձրացնելով դրա հնարավորություններն ու կայունությունը ինչպես հաճախորդի, այնպես էլ սերվերի կողմից մշակման համար:
Պատմական համատեքստ և նշանակություն.
- Փակելով բացը. մինչև ES6-ը JavaScript-ը չուներ մի քանի կառուցվածքներ, որոնք տարածված էին այլ լեզուներում, ինչը երբեմն ստիպում էր լեզուն ավելի քիչ հագեցած թվալ որոշակի տեսակի ծանրաբեռնված ծրագրերի համար: ES6-ն անդրադարձել է այս թերություններից շատերին:
- Ստանդարտացում. ES6-ը բերեց JavaScript-ի զարգացման նոր դարաշրջան՝ շեշտը դնելով ապագան պաշտպանելու և ստանդարտացված հատկանիշների վրա, որոնք ապահովում են հետևողականություն տարբեր JavaScript շարժիչների միջև:
- Մշակողի փորձ. ներդնելով նոր հնարավորությունների մի շարք՝ ES6-ը դարձրեց կոդը ավելի պարզ և արտահայտիչ՝ զգալիորեն բարելավելով ծրագրավորողների փորձը:
Հիմնական հատկանիշների ակնարկ
ES6-ը ներկայացրել է նոր հնարավորությունների փաթեթ, որոնք այդ ժամանակվանից դարձել են ժամանակակից JavaScript ծրագրավորման հիմնարար գործառույթներ: Ահա ամենաազդեցիկ հատկանիշներից մի քանիսի ակնարկ.
Սլաքի գործառույթները.
- Ապահովում է ավելի հակիրճ շարահյուսություն գրելու գործառույթների համար:
- Չունի իր սեփական
this, arguments, super, կամ new.targetկապանքները, ինչը նրանց դարձնում է իդեալական այն իրավիճակների համար, երբ ցանկանում եք պահպանել բառապաշարի thisարժեքը շրջապատող ծածկագրից:
const sum = (a, b) => a + b;
Դասեր:
- ES6-ում ներդրված JavaScript դասերը հիմնականում շարահյուսական են JavaScript-ի գոյություն ունեցող նախատիպի վրա հիմնված ժառանգության նկատմամբ և առաջարկում են շատ ավելի մաքուր և հստակ շարահյուսություն՝ օբյեկտներ ստեղծելու և ժառանգության հետ կապված:
class Rectangle {
constructor(height, width) {
this.height = height;
this.width = width;
}
}
Մոդուլներ:
- ES6 մոդուլները ներառում են գործառույթների, օբյեկտների և դասերի արտահանման և ներմուծման աջակցություն, ինչը մեծապես մեծացնում է կոդի կրկնակի օգտագործման և պահպանման հնարավորությունը:
// file1.js
export const pi = 3.14159;
// file2.js
import { pi } from './file1.js';
console.log(pi); // 3.14159
Կաղապարի բառացիությունը.
- Կաղապարների բառացիները հեշտ ճանապարհ են ստեղծում բազմագիծ տողեր ստեղծելու և տողերի ինտերպոլացիա կատարելու համար՝ հեշտացնելով ավելի ընթեռնելի ծածկագիրը:
const user = 'Jane';
console.log(`Hi ${user}, welcome back!`);
Կործանում:
- Destructuring-ը թույլ է տալիս կապել՝ օգտագործելով օրինաչափությունների համընկնումներ՝ համապատասխան զանգվածների և օբյեկտների աջակցությամբ: Destructuring-ը օգտակար է օբյեկտից կամ զանգվածից միաժամանակ մի քանի հատկություններ հանելու համար:
const [x, y] = [1, 2];
const {a, b} = {a:1, b:2};
Տարածման/Հանգստի օպերատորներ.
- Տարածման օպերատորը թույլ է տալիս կրկնվող, օրինակ՝ զանգվածի ընդլայնումը այն վայրերում, որտեղ ակնկալվում են զրո կամ ավելի արգումենտներ (ֆունկցիայի կանչերի համար) կամ էլեմենտներ (զանգվածի բառացիների համար): Մնացած օպերատորը հակառակն է անում՝ հավաքելով բազմաթիվ տարրեր և խտացնելով դրանք մեկ տարրի մեջ։
const nums = [1, 2, 3];
const numsCopy = [...nums]; // Spread as copying an array
function sum(...args) { // Rest as collecting function arguments
return args.reduce((total, n) => total + n, 0);
}
ES6-ով ներկայացված այս հատկանիշներից յուրաքանչյուրը խնամքով նախագծված է մշակման հատուկ կարիքները լուծելու համար՝ նպաստելով JavaScript-ի էվոլյուցիային՝ որպես հասուն և համապարփակ ծրագրավորման լեզու, որը հարմար է կիրառությունների լայն շրջանակի համար: Դասը կխորանա այս հատկանիշների մեջ՝ ցույց տալով, թե ինչպես դրանք կարող են արդյունավետ օգտագործվել ժամանակակից վեբ մշակման մեջ:
Սլաքի գործառույթները JavaScript-ում
Սլաքների ֆունկցիաների շարահյուսություն
Սլաքների ֆունկցիաները ներկայացնում են JavaScript-ում ֆունկցիաներ գրելու նոր և ավելի հակիրճ շարահյուսություն, որը ոչ միայն պարզեցնում է ֆունկցիայի հայտարարությունը, այլև փոխում է thisֆունկցիայի ներսում կապի ձևը:
Հիմնական շարահյուսություն.
Պարզ սլաքի գործառույթը հստակ պարամետրերով կարող է սահմանվել հետևյալ կերպ.
const add = (a, b) => a + b;
Այս ֆունկցիան վերցնում է երկու պարամետր և վերադարձնում դրանց գումարը։ Ուշադրություն դարձրեք հիմնաբառի բացակայությանը functionև =>.
Եթե ​​ֆունկցիան ունի միայն մեկ պարամետր, ապա պարամետրի շուրջ փակագծերը կարող են բաց թողնել.
const square = x => x * x;
Պարամետրեր չունեցող ֆունկցիաների կամ մի քանի հայտարարությունների համար դուք պետք է օգտագործեք փակագծեր և գանգուր փակագծեր, համապատասխանաբար.
const greet = () => console.log("Hello World!");
const multiply = (a, b) => {
let result = a * b;
return result;
};
thisՊարտադիր:
Ի տարբերություն ավանդական ֆունկցիաների, սլաքների ֆունկցիաները չունեն իրենց սեփական thisհամատեքստը: Փոխարենը, thisբառապաշարով ժառանգվում է արտաքին ֆունկցիայից, որտեղ սահմանված է սլաքի ֆունկցիան: Սա նշանակում է, որ սլաքային ֆունկցիայի ներսում thisնույնը մնում է ֆունկցիայի ողջ ցիկլի ընթացքում և միշտ կապված է thisամենամոտ ոչ սլաք մայր ֆունկցիայի արժեքին:
Առավելությունները և օգտագործումը
Լեքսիկական շրջանակը this.
Սլաքների գործառույթների հիմնական առավելությունը դրանց կառավարումն է this: Ավանդական ֆունկցիայի արտահայտություններում thisկարող է փոխվել՝ կախված այն համատեքստից, որում կոչվում է ֆունկցիան: Սլաքների գործառույթները շտկվում են this՝ հիմնվելով այն համատեքստի վրա, որտեղ ստեղծվել է ֆունկցիան, այլ ոչ թե այնտեղ, որտեղ այն կանչվել է: Սա սլաքների գործառույթները հատկապես օգտակար է դարձնում այն ​​սցենարներում, որտեղ գործառույթներն օգտագործվում են որպես փաստարկներ, ինչպիսիք են իրադարձությունների մշակողները կամ հետադարձ զանգերը:
Համառոտ շարահյուսություն.
Սլաքների գործառույթներն ապահովում են գործառույթները գրելու ավելի լակոնիկ եղանակ: Այս կարճ շարահյուսությունը օգտակար է ոչ միայն պարզ գործառույթների համար, այլև կոդն ավելի մաքուր և ընթեռնելի է դարձնում, հատկապես, երբ աշխատում եք ավելի բարձր կարգի ֆունկցիաների հետ, ինչպիսիք են map, filter-ը, կամ reduceորոնք սովորաբար ընդունում են հետադարձ կապի գործառույթները որպես փաստարկներ:
Գործնական վարժություն. ավանդական ֆունկցիաների վերամշակում
Նպատակը:
Վերափոխեք մի շարք ավանդական գործառույթներ սլաքների գործառույթների մեջ՝ ընդգծելով, թե ինչպես դա կարող է պարզեցնել կոդերի բազան և բարելավել ընթերցանությունը:
Նախքան վերամշակումը.
Զույգ թվերը զանգվածից զտելու ավանդական ֆունկցիա.
function filterEvens(numbers) {
return numbers.filter(function(number) {
return number % 2 === 0;
});
}
Ավանդական ֆունկցիա՝ թվերի զանգվածի ընդհանուր գումարը հաշվելու համար.
function computeTotal(numbers) {
return numbers.reduce(function(total, number) {
return total + number;
}, 0);
}
Վերափոխումից հետո.
Վերափոխվել է սլաքի ֆունկցիան օգտագործելու համար.
const filterEvens = numbers => numbers.filter(number => number % 2 === 0);
Վերափոխվել է սլաքի ֆունկցիան օգտագործելու համար.
const computeTotal = numbers => numbers.reduce((total, number) => total + number, 0);
Զորավարժությունների առաջադրանքներ.
- Ուղղորդեք ուսանողներին այս և պոտենցիալ ավելի բարդ գործառույթների փոխակերպման միջոցով:
- Քննարկեք, թե ինչպես է ռեֆակտորը փոխում իր վարքագիծը,
thisեթե այս գործառույթները լինեին օբյեկտի մեթոդներ, և ինչպես կարող է դա ազդել մեթոդի փոխազդեցության վրա օբյեկտի հատկությունների հետ:
- Խրախուսեք ուսանողներին ուսումնասիրել՝ օգտագործելով սլաքների ֆունկցիաները զանգվածի այլ մեթոդների հետ կամ որպես իրադարձությունների մշակիչներ, որտեղ բառապաշարը
thisօգտակար կլինի:
Այս վարժությունների միջոցով ուսանողները ոչ միայն կսովորեն գրել ավելի մաքուր, ավելի ժամանակակից JavaScript, այլև կհասկանան ֆունկցիաների կատարման համատեքստի որոշ նուրբ նրբերանգներ, մասնավորապես, թե ինչպես thisկարող է կապը հեշտացնել ծրագրավորման ընդհանուր օրինաչափությունների զարգացումը:
JavaScript-ի դասեր
Դասերի ներածություն
JavaScript-ի դասերը, որոնք ներդրվել են ES6-ում, ապահովում են շարահյուսական շաքար գոյություն ունեցող նախատիպի վրա հիմնված ժառանգության նկատմամբ և առաջարկում են ավելի հստակ և էլեգանտ շարահյուսություն՝ օբյեկտներ ստեղծելու և ժառանգականության հետ կապված: Մինչև ES6-ը, JavaScript-ում ժառանգությունն իրականացվում էր նախատիպային շղթաների միջոցով, որոնք կարող էին լինել մանրամասն և ոչ այնքան ինտուիտիվ, հատկապես այն ծրագրավորողների համար, ովքեր գալիս էին դասի վրա հիմնված լեզուներից, ինչպիսիք են Java-ն կամ C#-ը:
Շարահյուսություն և կառուցվածք.
- Դասի հռչակագիր . Դաս հայտարարելու համար օգտագործում եք
classբանալի բառը, որին հաջորդում է դասի անվանումը:
- Կառուցիչ .
constructorմեթոդը հատուկ մեթոդ է դասի հետ ստեղծված օբյեկտների ստեղծման և սկզբնավորման համար: Դասում կարող է լինել միայն մեկ կոնստրուկտորական մեթոդ:
- Մեթոդներ . Դասերը կարող են պարունակել բազմաթիվ մեթոդներ: Ի տարբերություն ֆունկցիայի արտահայտությունների, դասում սահմանված մեթոդները չեն բարձրացվում, ուստի դրանք չեն կարող կանչվել մինչև դասի մարմնում սահմանված լինելը:
class Rectangle {
constructor(height, width) {
this.height = height;
this.width = width;
}
area() {
return this.height * this.width;
}
}
Դասերի և ժառանգության ստեղծում
Դասի սահմանում . հիմնաբառի օգտագործումը classպարզեցնում է բարդ օբյեկտների սահմանումը իրենց նախատիպերով:
Ժառանգություն . Ժառանգությունը դաս ստեղծելու միջոց է որպես մեկ կամ մի քանի դասերի մասնագիտացված տարբերակ: JavaScript-ն իրականացնում է ժառանգությունը՝ օգտագործելով extendsհիմնաբառը:
extendsՀիմնաբառ . extendsՀիմնաբառը օգտագործվում է դասի հայտարարություններում կամ դասի արտահայտություններում՝ որպես մեկ այլ դասի երեխա դաս ստեղծելու համար:
Ժառանգության օրինակ .
class Person {
constructor(name) {
this.name = name;
}
greet() {
return `Hello, my name is ${this.name}`;
}
}
class Student extends Person {
constructor(name, level) {
super(name); // Call the parent class constructor
this.level = level;
}
study() {
return `${this.name} is studying at level ${this.level}`;
}
}
Գործնական օրինակներ
Դասերը աներևակայելի օգտակար են իրական աշխարհի սուբյեկտների և հարաբերությունների մոդելավորման համար: Ահա գործնական օրինակ, որը ներառում է Personդաս և Studentդաս, որը ժառանգում է դրանից.
let student = new Student("John", 12);
console.log(student.greet()); // "Hello, my name is John"
console.log(student.study()); // "John is studying at level 12"
Այս օրինակը ցույց է տալիս, թե ինչպես Studentէ ժառանգում ֆունկցիոնալությունը՝ Personավելացնելով իր յուրահատուկ վարքագիծը:
Ձեռքի վարժություն. Դասերի ստեղծում
Նպատակը . Ուսանողները կստեղծեն իրենց դասերը՝ պարփակելով ֆունկցիոնալությունը պարզ հավելվածի համար: Օրինակ հավելվածները ներառում են թվային ժամացույց կամ հիմնական գույքագրման համակարգ:
Թվային ժամացույցի օրինակ .
- Նպատակ . Ստեղծեք
Clockդաս, որը պահպանում է ընթացիկ ժամանակը և թարմացնում այն ​​ամեն վայրկյան:
- Իրականացում .
class Clock {
constructor() {
this.currentTime = new Date();
this.updateTime();
}
updateTime() {
setInterval(() => {
this.currentTime = new Date(); // Update time every second
console.log(this.currentTime.toLocaleTimeString()); // Display time
}, 1000);
}
}
const myClock = new Clock(); // Create a new clock instance
Հիմնական գույքագրման համակարգ .
- Նպատակը . Մշակել
Inventoryդաս, որը թույլ է տալիս ավելացնել և հետևել տարրեր:
- Իրականացում .
class Inventory {
constructor() {
this.items = [];
}
addItem(item) {
this.items.push(item);
console.log(`Added ${item} to inventory`);
}
listItems() {
console.log("Inventory Items:");
this.items.forEach(item => console.log(item));
}
}
const myInventory = new Inventory();
myInventory.addItem("Backpack");
myInventory.addItem("Notebook");
myInventory.listItems();
Այս վարժությունները գործնական ճանապարհ են տալիս ուսանողներին կիրառելու իրենց գիտելիքները JavaScript-ի դասերի վերաբերյալ՝ ուսումնասիրելով ինչպես ժառանգականությունը, այնպես էլ դասի կառուցվածքում ֆունկցիոնալության ամփոփումը: Նպատակն է ցույց տալ, թե ինչպես դասերը կարող են օգտագործվել հավելվածների ավելի արդյունավետ կառուցվածքի համար՝ բարձրացնելով ընթերցելիությունը և պահպանելիությունը:
Մոդուլներ JavaScript-ում
Ինչու՞ օգտագործել մոդուլներ:
Մոդուլները մասշտաբային և պահպանվող ծրագրերի կառուցման էական կողմն են: Ծրագիրը ֆունկցիոնալության առանձին մասերի բաժանելով՝ մոդուլներն առաջարկում են մի քանի առավելություններ.
Պահպանելիություն . ավելի փոքր, լավ սահմանված մոդուլները ավելի հեշտ են հասկանալ, կարգաբերել և թարմացնել՝ համեմատած խոշոր մոնոլիտ կոդերի հիմքերի հետ: Յուրաքանչյուր մոդուլ ունի հստակ ուշադրություն և կարող է պահպանվել մյուսներից անկախ:
Կրկնակի օգտագործման հնարավորություն . մոդուլները թույլ են տալիս վերօգտագործել կոդը հավելվածի տարբեր մասերում կամ նույնիսկ տարբեր նախագծերի միջև: Օրինակ, մոդուլի մշակման ամսաթվի և ժամի գործառնությունները կարող են կրկին օգտագործվել այնտեղ, որտեղ նման գործառույթ է պահանջվում՝ առանց կրկնօրինակման:
Անվան տարածության կառավարում . մոդուլներն օգնում են խուսափել գլոբալ անվանումների տարածքի աղտոտումից: Նրանք ամփոփում են իրենց փոփոխականներն ու գործառույթները՝ բացահայտելով միայն այն, ինչ բացահայտ արտահանվում է: Սա նվազեցնում է ձեր կոդերի բազայի միջև կոնֆլիկտների անվանման ռիսկը:
Կախվածության կառավարում . մոդուլների միջոցով պարզ է, թե որ ֆայլերը որ այլ ֆայլերից են կախված՝ ավելի պարզ դարձնելով նախագծերի կառուցվածքը և օգնելով ապահովել, որ սցենարները բեռնված են ճիշտ հերթականությամբ:
Մոդուլների արտահանում և ներմուծում
Մոդուլի արտահանում .
Անվանված արտահանումներ . Դուք կարող եք արտահանել բազմաթիվ օբյեկտներ, գործառույթներ կամ պրիմիտիվներ մոդուլից՝ օգտագործելով անվանված արտահանումները: Յուրաքանչյուր արտահանում ներմուծման ժամանակ կարող է նշվել իր անունով:
// utils.js
export const add = (a, b) => a + b;
export const multiply = (a, b) => a * b;
Կանխադրված արտահանում . Յուրաքանչյուր մոդուլ կարող է կամայականորեն արտահանել մեկ լռելյայն արտահանում, որը համարվում է հիմնական «արժեքը», որը տրամադրում է մոդուլը:
// greeting.js
export default function greet(name) {
return `Hello, ${name}!`;
}
Մոդուլի ներմուծում .
Անվանված արտահանումների ներմուծում . Դուք կարող եք ներմուծել մոդուլի որոշակի մասեր՝ օգտագործելով անվանված արտահանումները:
// app.js
import { add, multiply } from './utils.js';
console.log(add(2, 3)); // Output: 5
console.log(multiply(2, 3)); // Output: 6
Կանխադրված արտահանումների ներմուծում . լռելյայն արտահանումները ներմուծվում են առանց փակագծերի օգտագործման:
// main.js
import greet from './greeting.js';
console.log(greet('Alice')); // Output: Hello, Alice!
Գործնական գործունեություն. փոքր հավելվածի մոդուլյարացում
Նպատակը . Ուսանողները պարզ հավելվածը կդարձնեն տարբեր բաղադրիչներ: Ենթադրենք հիմնական հավելված, որը ցուցադրում է օգտվողի տվյալները:
Կառուցվածքը :
Տվյալների մոդուլ . պահում է օգտատիրոջ տվյալները:
Տրամաբանական մոդուլ . Պարունակում է բիզնես տրամաբանություն, ինչպես օգտատիրոջ անունով գտնելու գործառույթը:
Ներկայացման մոդուլ . Բռնակներ ցուցադրում է տեղեկատվություն վահանակում կամ DOM-ում:
Հիմնական հայտի ֆայլ .
Առաջադրանք .
- Յուրաքանչյուր ուսանող կստեղծի այս մոդուլները և կկապի դրանք միասին՝ օգտագործելով ES6 մոդուլի շարահյուսությունը:
- Ընտրովի, ուսանողները կարող են ավելացնել ավելի շատ գործառույթներ, ինչպիսիք են օգտվողի տվյալների թարմացումը կամ ջնջումը, բարդ գործառույթների մոդուլյարացման համար:
Այս գործողությունը գործնական օրինակ է տալիս, թե ինչպես կարող են ES6 մոդուլները օգտագործվել իրական աշխարհի հավելվածում կոդը կազմակերպելու համար՝ ընդգծելով մտահոգությունների մաքուր տարանջատումը և բարելավելով կոդի կառավարելիությունը:
ES6-ի լրացուցիչ հնարավորություններ
Կաղապար բառացիներ
Կաղապարի բառացիները ուժեղացնում են բարդ տողերի ստեղծումը՝ թույլ տալով ներկառուցված արտահայտություններ և բազմագիծ տողեր՝ առանց կապակցման օպերատորների ( +): Դրանք պարփակված են հետինտողերով (``), այլ ոչ թե ավանդական մեկ կամ կրկնակի չակերտներով:
Կաղապարի Literals-ի առանձնահատկությունները.
- Բազմատող տողեր. Հեշտությամբ ստեղծեք տողեր, որոնք ընդգրկում են մի քանի տողեր՝ առանց նոր տողերի նիշերը ձեռքով ներառելու անհրաժեշտության:
- Արտահայտման ինտերպոլացիա. Տեղադրեք արտահայտություններ անմիջապես տողի մեջ՝ օգտագործելով
${expression}շարահյուսությունը, որը գնահատվում և փոխարկվում է տողի:
Օգտագործման օրինակ.
const name = "Alice";
const age = 25;
const greeting = `Hello, my name is ${name} and I am ${age} years old.`;
console.log(greeting);
// Output: Hello, my name is Alice and I am 25 years old.
Կործանում
Destructuring-ը թույլ է տալիս զանգվածներից կամ հատկություններից արժեքները հանել օբյեկտներից՝ առանձին փոփոխականների մեջ:
Զանգվածի ապակառուցում.
- Քաղեք տարրեր զանգվածից և վերագրեք դրանք փոփոխականներին:
const numbers = [1, 2, 3];
const [one, two, three] = numbers;
console.log(one, two, three); // Output: 1 2 3
Օբյեկտների ոչնչացում.
- Հատկություններ հանել օբյեկտից:
const user = { name: "John", age: 30 };
const { name, age } = user;
console.log(name, age); // Output: John 30
Տարածման և հանգստի օպերատորներ
Spread Operator ( ...):
- Զանգվածներ. զանգվածի տարրերը տարածեք նոր զանգվածի մեջ:
const parts = ['shoulders', 'knees'];
const bodyParts = ['head', ...parts, 'toes'];
console.log(bodyParts); // Output: ["head", "shoulders", "knees", "toes"]
- Օբյեկտներ. պատճենեք հատկությունները մեկ օբյեկտից մյուսը:
const item = { name: 'Coffee', price: 2 };
const updatedItem = { ...item, price: 3 };
console.log(updatedItem); // Output: { name: 'Coffee', price: 3 }
Հանգստի պարամետրեր.
- Ներկայացրե՛ք անորոշ թվով արգումենտներ որպես զանգված:
function sum(...numbers) {
return numbers.reduce((total, n) => total + n, 0);
}
console.log(sum(1, 2, 3)); // Output: 6
Գործնական վարժություններ
Նպատակը. Ուսանողները կիրառում են ձևանմուշների բառացի, ապակառուցողական և տարածման/հանգստի օպերատորներ՝ պարզեցնելու և բարելավելու JavaScript հատվածների ֆունկցիոնալությունը:
Օրինակ վարժություն. Բարելավել գործառույթը, որը մշակում է նոր օգտվողի տվյալները ներկայացնող օբյեկտը:
Տրամադրված հատված՝
function createUser(displayName, email, id) {
return {
displayName: displayName,
email: email,
id: id
};
}
Բարելավված տարբերակ՝ օգտագործելով ES6-ի առանձնահատկությունները.
- Refactor with Destructuring and Object Property Shortthand:
function createUser(user) {
const { displayName, email, id } = user;
return { displayName, email, id };
}
// Usage
const userData = { displayName: "Alice", email: "alice@example.com", id: 1 };
console.log(createUser(userData));
- Ներառեք ձևանմուշների բառացի նշումներ արդյունքի համար.
function displayUserInfo(user) {
const info = `User: ${user.displayName}, Email: ${user.email}`;
console.log(info);
}
displayUserInfo(userData);
Առաջադրանք. Ուսանողները պետք է վերցնեն կոդի հատված, որը ձեռքով միացնում է տողերը և օգտագործում ինդեքսի վրա հիմնված հասանելիություն զանգվածների և օբյեկտների համար, և վերամշակում այն՝ օգտագործելով քննարկված ES6 հատկանիշները: Սա ցույց կտա այն ուժն ու պարզությունը, որ այս հատկանիշները բերում են JavaScript-ին՝ կոդն ավելի ընթեռնելի և պահպանելի դարձնելով:
Урок 15. Возможности ES6: стрелочные функции, классы и модули
Введение в ES6 (ECMAScript 2015)
Обзор ES6
ECMAScript 6, также известный как ES6 и официально как ECMAScript 2015, представляет собой значительное обновление JavaScript, отмечая первое крупное обновление языка с момента стандартизации ES5 в 2009 году. ES6 представил несколько новых функций и улучшений синтаксиса, которые модернизировали JavaScript, сделав его более удобным. мощный, эффективный и простой в использовании, особенно для разработки сложных приложений. Это обновление сыграло решающую роль в более тесном согласовании JavaScript с другими языками программирования высокого уровня, расширив его возможности и надежность как для клиентской, так и для серверной разработки.
Исторический контекст и значение:
- Устранение разрыва: до ES6 в JavaScript отсутствовало несколько конструкций, которые были распространены в других языках, из-за чего иногда язык казался менее приспособленным для определенных типов тяжелых приложений. ES6 устранил многие из этих недостатков.
- Стандартизация: ES6 открыл новую эру разработки JavaScript с упором на перспективность и стандартизированные функции, которые обеспечивают согласованность между различными движками JavaScript.
- Опыт разработчика. Введя множество новых функций, ES6 сделал код более простым и выразительным, что значительно улучшило работу разработчиков.
Обзор основных функций
ES6 представил набор новых функций, которые с тех пор стали фундаментальными для современного программирования на JavaScript. Вот обзор некоторых из наиболее эффективных функций:
Функции стрелок:
- Предоставляет более краткий синтаксис для написания функций.
- Не имеет собственных
this, arguments, superили new.targetпривязок, что делает их идеальными для ситуаций, когда вы хотите сохранить лексическое thisзначение из окружающего кода.
const sum = (a, b) => a + b;
Классы:
- Классы JavaScript, представленные в ES6, в первую очередь представляют собой синтаксический сахар по сравнению с существующим в JavaScript наследованием на основе прототипов и предлагают гораздо более чистый и понятный синтаксис для создания объектов и работы с наследованием.
class Rectangle {
constructor(height, width) {
this.height = height;
this.width = width;
}
}
Модули:
- Модули ES6 включают поддержку экспорта и импорта функций, объектов и классов, что значительно повышает удобство повторного использования и сопровождения кода.
// file1.js
export const pi = 3.14159;
// file2.js
import { pi } from './file1.js';
console.log(pi); // 3.14159
Литералы шаблона:
- Литералы шаблонов предоставляют простой способ создания многострочных строк и выполнения интерполяции строк, что делает код более читаемым.
const user = 'Jane';
console.log(`Hi ${user}, welcome back!`);
Деструктуризация:
- Деструктуризация позволяет выполнять связывание с использованием сопоставления с образцом с поддержкой сопоставления массивов и объектов. Деструктуризация полезна для одновременного извлечения нескольких свойств из объекта или массива.
const [x, y] = [1, 2];
const {a, b} = {a:1, b:2};
Операторы распространения/остановки:
- Оператор расширения позволяет расширять итерацию, например массив, в тех местах, где ожидается ноль или более аргументов (для вызовов функций) или элементов (для литералов массива). Оператор rest делает обратное, собирая несколько элементов и объединяя их в один элемент.
const nums = [1, 2, 3];
const numsCopy = [...nums]; // Spread as copying an array
function sum(...args) { // Rest as collecting function arguments
return args.reduce((total, n) => total + n, 0);
}
Каждая из этих функций, представленных в ES6, была тщательно разработана для удовлетворения конкретных потребностей разработки, способствуя развитию JavaScript как зрелого и комплексного языка программирования, подходящего для широкого спектра приложений. На уроке мы углубимся в эти функции, показав, как их можно эффективно использовать в современной веб-разработке.
Стрелочные функции в JavaScript
Синтаксис стрелочных функций
Стрелочные функции представляют новый и более краткий синтаксис для написания функций в JavaScript, который не только упрощает объявление функции, но и меняет способ thisпривязки внутри функции.
Основной синтаксис:
Простую стрелочную функцию с явными параметрами можно определить следующим образом:
const add = (a, b) => a + b;
Эта функция принимает два параметра и возвращает их сумму. Обратите внимание на отсутствие functionключевого слова и использование =>.
Если функция имеет только один параметр, круглые скобки вокруг параметра можно опустить:
const square = x => x * x;
Для функций без параметров или с несколькими операторами необходимо использовать круглые и фигурные скобки соответственно:
const greet = () => console.log("Hello World!");
const multiply = (a, b) => {
let result = a * b;
return result;
};
thisОбвязка:
В отличие от традиционных функций, стрелочные функции не имеют собственного thisконтекста. Вместо этого thisлексически наследуется от внешней функции, в которой определена стрелочная функция. Это означает, что внутри стрелочной функции thisостается неизменным на протяжении всего жизненного цикла функции и всегда привязано к thisзначению ближайшей родительской функции, не являющейся стрелкой.
Преимущества и использование
Лексическое определение this:
Основным преимуществом стрелочных функций является их обработка this. В традиционных выражениях функций thisможет меняться в зависимости от контекста, в котором вызывается функция. Стрелочные функции исправляются thisв зависимости от контекста, в котором функция создается, а не от того, где она вызывается. Это делает стрелочные функции особенно полезными в сценариях, где функции используются в качестве аргументов, например, в обработчиках событий или обратных вызовах.
Краткий синтаксис:
Стрелочные функции предоставляют более лаконичный способ написания функций. Этот более короткий синтаксис полезен не только для простых функций, но также делает код более чистым и читабельным, особенно при работе с функциями более высокого порядка, такими как map, filterили reduceкоторые обычно принимают функции обратного вызова в качестве аргументов.
Практическое упражнение: рефакторинг традиционных функций
Цель:
Реорганизуйте ряд традиционных функций в функции стрелок, подчеркнув, как это может упростить базу кода и улучшить читаемость.
Перед рефакторингом:
Традиционная функция для фильтрации четных чисел из массива:
function filterEvens(numbers) {
return numbers.filter(function(number) {
return number % 2 === 0;
});
}
Традиционная функция для вычисления суммы массива чисел:
function computeTotal(numbers) {
return numbers.reduce(function(total, number) {
return total + number;
}, 0);
}
После рефакторинга:
Рефакторинг для использования функции стрелки:
const filterEvens = numbers => numbers.filter(number => number % 2 === 0);
Рефакторинг для использования функции стрелки:
const computeTotal = numbers => numbers.reduce((total, number) => total + number, 0);
Задачи упражнения:
- Помогите учащимся преобразовать эти и, возможно, более сложные функции.
- Обсудите, как рефакторинг меняет поведение,
thisесли эти функции были методами объекта, и как это может повлиять на взаимодействие метода со свойствами объекта.
- Поощряйте учащихся изучать использование стрелочных функций с другими методами работы с массивами или в качестве обработчиков событий, где лексика
thisбудет полезна.
С помощью этих упражнений учащиеся не только научатся писать более чистый и современный JavaScript, но также поймут некоторые тонкие нюансы контекста выполнения функций, в частности, как thisсвязывание может упростить разработку в общих шаблонах программирования.
Классы в JavaScript
Введение в классы
Классы в JavaScript, представленные в ES6, обеспечивают синтаксическую «добавку» к существующему наследованию на основе прототипов и предлагают более ясный и элегантный синтаксис для создания объектов и работы с наследованием. До ES6 наследование в JavaScript осуществлялось через цепочки прототипов, которые могли быть многословными и не такими интуитивно понятными, особенно для разработчиков, использующих языки на основе классов, такие как Java или C#.
Синтаксис и структура:
- Объявление класса . Чтобы объявить класс, вы используете
classключевое слово, за которым следует имя класса.
- Конструктор :
constructorметод представляет собой специальный метод для создания и инициализации объектов, созданных с помощью класса. В классе может быть только один метод-конструктор.
- Методы . Классы могут содержать несколько методов. В отличие от выражений функций, методы, определенные в классе, не поднимаются, поэтому их нельзя вызвать до того, как они будут определены в теле класса.
class Rectangle {
constructor(height, width) {
this.height = height;
this.width = width;
}
area() {
return this.height * this.width;
}
}
Создание классов и наследование
Определение класса . Использование classключевого слова упрощает определение сложных объектов с их собственными прототипами.
Наследование . Наследование — это способ создания класса как специализированной версии одного или нескольких классов. JavaScript реализует наследование с использованием extendsключевого слова.
extendsКлючевое слово : extendsКлючевое слово используется в объявлениях классов или выражениях классов для создания класса как дочернего элемента другого класса.
Пример наследования :
class Person {
constructor(name) {
this.name = name;
}
greet() {
return `Hello, my name is ${this.name}`;
}
}
class Student extends Person {
constructor(name, level) {
super(name); // Call the parent class constructor
this.level = level;
}
study() {
return `${this.name} is studying at level ${this.level}`;
}
}
Практические примеры
Классы невероятно полезны для моделирования реальных объектов и отношений. Вот практический пример, включающий Personкласс и Studentкласс, который от него наследуется:
let student = new Student("John", 12);
console.log(student.greet()); // "Hello, my name is John"
console.log(student.study()); // "John is studying at level 12"
Этот пример иллюстрирует, как Studentнаследуется функциональность Personпри добавлении собственного уникального поведения.
Практическое упражнение: создание классов
Цель : учащиеся создадут свои собственные классы, воплощающие функциональность простого приложения. Примеры приложений включают цифровые часы или базовую систему инвентаризации.
Пример цифровых часов :
- Цель : создать
Clockкласс, который поддерживает текущее время и обновляет его каждую секунду.
- Выполнение :
class Clock {
constructor() {
this.currentTime = new Date();
this.updateTime();
}
updateTime() {
setInterval(() => {
this.currentTime = new Date(); // Update time every second
console.log(this.currentTime.toLocaleTimeString()); // Display time
}, 1000);
}
}
const myClock = new Clock(); // Create a new clock instance
Базовая система инвентаря :
- Цель : разработать
Inventoryкласс, позволяющий добавлять и отслеживать элементы.
- Выполнение :
class Inventory {
constructor() {
this.items = [];
}
addItem(item) {
this.items.push(item);
console.log(`Added ${item} to inventory`);
}
listItems() {
console.log("Inventory Items:");
this.items.forEach(item => console.log(item));
}
}
const myInventory = new Inventory();
myInventory.addItem("Backpack");
myInventory.addItem("Notebook");
myInventory.listItems();
Эти упражнения дают учащимся практический способ применить свои знания о классах JavaScript, изучая как наследование, так и инкапсуляцию функциональности в структурах классов. Цель состоит в том, чтобы проиллюстрировать, как классы можно использовать для более эффективного структурирования приложений, улучшая читаемость и удобство обслуживания.
Модули в JavaScript
Зачем использовать модули?
Модули являются важным аспектом создания масштабируемых и удобных в обслуживании приложений. Разделив программу на отдельные фрагменты функциональности, модули дают несколько преимуществ:
Удобство сопровождения . Меньшие, четко определенные модули легче понимать, отлаживать и обновлять по сравнению с большими монолитными базами кода. Каждый модуль имеет четкую направленность и может поддерживаться независимо от других.
Возможность повторного использования . Модули позволяют повторно использовать код в разных частях приложения или даже между разными проектами. Например, модуль, обрабатывающий операции с датой и временем, можно повторно использовать везде, где требуется такая функциональность, без дублирования.
Управление пространством имен : модули помогают избежать глобального загрязнения пространства имен. Они инкапсулируют свои переменные и функции, раскрывая только то, что явно экспортируется. Это снижает риск конфликтов имен в вашей кодовой базе.
Управление зависимостями : с помощью модулей становится ясно, какие файлы зависят от других файлов, что делает структуру проектов более понятной и помогает гарантировать, что сценарии загружаются в правильном порядке.
Экспорт и импорт модулей
Экспорт модуля :
Именованный экспорт : вы можете экспортировать несколько объектов, функций или примитивов из модуля, используя именованный экспорт. При импорте на каждый экспорт можно ссылаться по собственному имени.
// utils.js
export const add = (a, b) => a + b;
export const multiply = (a, b) => a * b;
Экспорт по умолчанию : каждый модуль может дополнительно экспортировать один экспорт по умолчанию, который считается основным «значением», предоставляемым модулем.
// greeting.js
export default function greet(name) {
return `Hello, ${name}!`;
}
Импорт модуля :
Импорт именованных экспортов . Вы можете импортировать определенные части модуля, используя именованные экспорты.
// app.js
import { add, multiply } from './utils.js';
console.log(add(2, 3)); // Output: 5
console.log(multiply(2, 3)); // Output: 6
Импорт экспорта по умолчанию : экспорт по умолчанию импортируется без использования скобок.
// main.js
import greet from './greeting.js';
console.log(greet('Alice')); // Output: Hello, Alice!
Практическое занятие: Модуляризация небольшого приложения
Цель : учащиеся разобьют простое приложение на отдельные компоненты. Предположим, что это базовое приложение, отображающее пользовательские данные.
Состав :
Модуль данных : содержит пользовательские данные.
Модуль логики : содержит бизнес-логику, например функцию поиска пользователя по имени.
Модуль презентации : управляет отображением информации в консоли или в DOM.
Основной файл приложения :
Задача :
- Каждый студент создаст эти модули и свяжет их вместе, используя синтаксис модулей ES6.
- При желании учащиеся могут добавить дополнительные функции, такие как обновление или удаление пользовательских данных, чтобы попрактиковаться в модульности сложных функций.
Это занятие представляет собой практический пример того, как модули ES6 можно использовать для организации кода в реальном приложении, подчеркивая чистое разделение задач и улучшая управляемость кода.
Дополнительные возможности ES6
Литералы шаблонов
Литералы шаблонов расширяют возможности создания сложных строк, позволяя использовать встроенные выражения и многострочные строки без необходимости использования операторов конкатенации ( +). Они заключаются в обратные кавычки (``), а не в традиционные одинарные или двойные кавычки.
Особенности шаблонных литералов:
- Многострочные строки: легко создавайте строки, занимающие несколько строк, без необходимости вручную включать символы новой строки.
- Интерполяция выражений: вставляйте выражения непосредственно в строку, используя
${expression}синтаксис, который оценивается и преобразуется в строку.
Пример использования:
const name = "Alice";
const age = 25;
const greeting = `Hello, my name is ${name} and I am ${age} years old.`;
console.log(greeting);
// Output: Hello, my name is Alice and I am 25 years old.
Деструктуризация
Деструктуризация позволяет распаковывать значения из массивов или свойства объектов в отдельные переменные.
Деструктуризация массива:
- Извлекайте элементы из массива и присваивайте их переменным.
const numbers = [1, 2, 3];
const [one, two, three] = numbers;
console.log(one, two, three); // Output: 1 2 3
Деструктуризация объекта:
- Извлечение свойств из объекта.
const user = { name: "John", age: 30 };
const { name, age } = user;
console.log(name, age); // Output: John 30
Операторы распространения и отдыха
Оператор распространения ( ...):
- Массивы: распространение элементов массива в новый массив.
const parts = ['shoulders', 'knees'];
const bodyParts = ['head', ...parts, 'toes'];
console.log(bodyParts); // Output: ["head", "shoulders", "knees", "toes"]
- Объекты: копирование свойств одного объекта в другой.
const item = { name: 'Coffee', price: 2 };
const updatedItem = { ...item, price: 3 };
console.log(updatedItem); // Output: { name: 'Coffee', price: 3 }
Параметры покоя:
- Представляйте неопределенное количество аргументов в виде массива.
function sum(...numbers) {
return numbers.reduce((total, n) => total + n, 0);
}
console.log(sum(1, 2, 3)); // Output: 6
Практические упражнения
Цель: учащиеся применяют литералы шаблонов, операторы деструктуризации и расширения/остановки для упрощения и улучшения функциональности фрагментов JavaScript.
Пример упражнения: Улучшите функцию, обрабатывающую объект, представляющий данные нового пользователя.
Предоставленный фрагмент:
function createUser(displayName, email, id) {
return {
displayName: displayName,
email: email,
id: id
};
}
Улучшенная версия с использованием функций ES6:
- Рефакторинг с деструктуризацией и сокращением свойств объекта:
function createUser(user) {
const { displayName, email, id } = user;
return { displayName, email, id };
}
// Usage
const userData = { displayName: "Alice", email: "alice@example.com", id: 1 };
console.log(createUser(userData));
- Включите литералы шаблона для вывода:
function displayUserInfo(user) {
const info = `User: ${user.displayName}, Email: ${user.email}`;
console.log(info);
}
displayUserInfo(userData);
Задача: учащиеся должны взять фрагмент кода, который вручную объединяет строки и использует индексный доступ к массивам и объектам, и провести его рефакторинг с использованием обсуждаемых функций ES6. Это продемонстрирует мощь и простоту, которые эти функции привносят в JavaScript, делая код более читабельным и удобным в сопровождении.