Изучение методов call(), apply() иbind() важно, поскольку они позволяют вам контролировать контекст этого в JavaScript. В ситуациях, когда по умолчанию это поведение не работает должным образом, например, при заимствовании методов из одного объекта в другой или поддержании правильного контекста внутри обратных вызовов, эти методы обеспечивают гибкость и контроль. Освоив их, вы сможете писать более эффективные, многократно используемые и контекстно-зависимые функции, что особенно полезно в сложных приложениях.
прежде чем мы перейдем к методам call(), apply() иbind(), давайте разберемся с ключевым словом this и его механизмом.
Давайте поймем, когда и что означает это ключевое слово, по следующим пунктам:
В методе объекта this ссылается на объект. Внутри метода, определенного внутри объекта, это будет указывать на объект, которому принадлежит этот метод.
В обычной функции this относится к глобальному объекту. В нестрогом режиме, если функция вызывается в глобальном контексте (а не как метод объекта), это относится к глобальному объекту (окну в браузерах).
В функции строгого режима это значение не определено. Если функция не является методом объекта и не привязана к определенному контексту (посредством вызова, применения или привязки), в строгом режиме она будет неопределена.
В обработчиках событий это относится к элементу, получившему событие. Когда событие инициируется, это относится к элементу HTML, который вызвал это событие.
В данном случае это относится к самому элементу кнопки, получившему событие onclick.
В стрелочных функциях это ведет себя по-другому. Стрелочные функции не имеют собственного контекста this. Вместо этого это лексически наследуется от окружающей области видимости во время создания функции стрелки. Это означает, что this внутри функции стрелки будет ссылаться на this ее включающей функции или контекста.
const person = { name: "Alice", greet: function() { setTimeout(() => { console.log(`Hi, I'm ${this.name}`); }, 1000); } }; person.greet(); // Output: Hi, I'm Alice
В этом случае стрелочная функция внутри setTimeout наследует это от методаприветствия, который указывает на объект person.
Метод call() позволяет вам «заимствовать» функцию или метод из одного объекта и использовать ее с другим объектом, передав другой объект в качестве первого аргумента. Первым аргументом внутри функции становится значение this, а после него следуют дополнительные аргументы.
Метод call() не создает новую функцию; он запускает существующую функцию с предоставленным контекстом и аргументами.
const person = { fullName: function(city, country) { console.log(this.firstName " " this.lastName " is going to " city ", " country "."); } } const person1 = { firstName: "John", lastName: "Doe" } person.fullName.call(person1, "Oslo", "Norway"); // Output: John Doe is going to Oslo, Norway.
В этом примере call() используется для выполнения метода fullName человека с данными person1 (firstName и LastName), а дополнительными аргументами являются «Осло» и «Норвегия».
Метод apply() очень похож на метод call(). Основное отличие заключается в том, как аргументы передаются в функцию. С помощью apply() вы передаете аргументы как массив (или объект, подобный массиву), а не по отдельности.
Как и call(), метод apply() не создает новую функцию. Он немедленно выполняет функцию с предоставленным контекстом (это значение) и аргументами.
const person = { fullName: function(city, country) { console.log(this.firstName " " this.lastName " is going to " city ", " country "."); } } const person1 = { firstName: "John", lastName: "Doe" } person.fullName.apply(person1, ["Oslo", "Norway"]); // Output: John Doe is going to Oslo, Norway.
В этом примере метод apply() используется для вызова метода fullName объекта person, но с контекстом (this) person1. Аргументы «Осло» и «Норвегия» передаются как массив.
Метод bind() в JavaScript позволяет вам установить контекст (это значение) для функции или метода, точно так же, как call() и apply(). Однако, в отличие от call() и apply(), методbind() не вызывает функцию немедленно. Вместо этого она возвращает новую функцию со значением this, установленным для указанного вами объекта.
const person = { fullName: function(city, country) { console.log(this.firstName " " this.lastName " is going to " city ", " country "."); } } const person1 = { firstName: "John", lastName: "Doe" } const func = person.fullName.bind(person1); func("Oslo", "Norway"); // Output: John Doe is going to Oslo, Norway.
В этом примере метод bind() создает новую функцию func со значением this, установленным на person1. Функция не вызывается сразу, но вы можете вызвать ее позже, передав аргументы «Осло» и «Норвегия».
Вот небольшой, но сложный пример приложения, в котором использование call(), apply() илиbind() повышает эффективность, особенно при обработке частичного применения функций для целей журналирования:
Предположим, у вас есть функция централизованного журналирования, которая записывает информацию о действиях разных пользователей. Использование метода связывания() позволяет эффективно устанавливать контекст this для разных пользователей, избегая повторения кода.
const logger = { logAction: function(action) { console.log(`${this.name} (ID: ${this.id}) performed: ${action}`); } }; const user1 = { name: "Alice", id: 101 }; const user2 = { name: "Bob", id: 202 }; // Create new logger functions for different users const logForUser1 = logger.logAction.bind(user1); const logForUser2 = logger.logAction.bind(user2); // Perform actions without manually passing user context logForUser1("login"); // Output: Alice (ID: 101) performed: login logForUser2("purchase"); // Output: Bob (ID: 202) performed: purchase
Повторное использование контекста: Вам не нужно вручную передавать контекст пользователя каждый раз, когда вы регистрируете действие. Контекст (this) привязывается один раз, и журналирование становится многоразовым и чистым.
Модульность: Если вам нужно добавить больше пользователей или действий, вы можете быстро привязать их к регистратору, не изменяя саму функцию, сохраняя свой код СУХИМ (не повторяйте себя).
Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.
Copyright© 2022 湘ICP备2022001581号-3