Какова механика работы метода bind?
Я понимаю, зачем нужен метод bind и чисто механически вижу эффект. Но не понимаю механику его работы и вот почему:
У Ильи кантора написано следующее:
Результатом вызова func.bind(context) является особый «экзотический объект» (термин взят из спецификации), который вызывается как функция и прозрачно передаёт вызов в func, при этом устанавливая this=context.
У Флэнагана вот это:
When you invoke the bind() method on a function f and pass an
object o, the method returns a new function. Invoking the new function
(as a function) invokes the original function f as a method of o.
Несмотря на различия в трактовке результирующего объекта, у них общая ключевая мысль - полученный в результате bind'а объект передает вызов оригинальной функции. Т.е. он не является как бы ее копией, работающей самостоятельно в отрыве от оригинала, а именно передает вызов оригиналу. Ну это как я понял эти определения.
В связи с этим я не понимаю, почему при замене оригинальной функции в объекте на другую, продолжает вызываться изначальная версия. Хотя если изменить данные, то берутся новые:
let user = { name: "Tom", intro() { console.log("I am " + this.name); } } let f = user.intro.bind(user); setTimeout(f, 1000); user.name = "Sid"; user.intro = function() { console.log("Вообще другая функция. name: " + this.name); } |
let user = { name: "Tom", intro() { console.log("I am " + this.name); } } let f = user.intro.bind(user); setTimeout(f, 1000); user.name = "Sid"; user.intro = function() { console.log("Вообще другая функция. name: " + this.name); }
Получаем в результате фразу "I am Sid", т.е. новые данные увиделись, а функция осталась старая. Выглядит так как будто при бинде именно создается копия исходной функции и вызывается именно она, безо всяких переадресаций.
Дополнительно:
Что бы понять, что происходит, достаточно написать полифил:
const myBind = (f, that) => { return (...args) => f.apply(that, args) } |
const myBind = (f, that) => { return (...args) => f.apply(that, args) }
bind кэширует текущее значение своего this в момент своего вызова, т.е. он привязывает именно функцию, а не объект, в котором находится функция. Иначе нельзя было бы вызывать bind на просто функции по типу foo.bind(abc). В мануале, кстати, описано что именно она кэширует - там полный список есть: https://developer.mozilla.org/ru/docs/Web/JavaScri...
Упрощенный пример реализации bind для понимания механизма:
function binder(that) { let targetFunction = this; // кэш целевой функции return function() { targetFunction.call(that) } // В возвращаемой функции используем кэш } let user = { name: "Tom", intro() { console.log("I am " + this.name); } } user.intro.binder = binder let f = user.intro.binder(user); setTimeout(f, 1000); user.name = "Sid"; user.intro = function() { console.log("Вообще другая функция. name: " + this.name); } |
function binder(that) { let targetFunction = this; // кэш целевой функции return function() { targetFunction.call(that) } // В возвращаемой функции используем кэш } let user = { name: "Tom", intro() { console.log("I am " + this.name); } } user.intro.binder = binder let f = user.intro.binder(user); setTimeout(f, 1000); user.name = "Sid"; user.intro = function() { console.log("Вообще другая функция. name: " + this.name); }
- Хороший пример на самодельный binder, теперь понятно в чем дело.
Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.
Пока нет других ответов. Будьте первым, кто поможет автору.
Ответить на вопрос
Метод bind() в PHP используется для привязки значений к параметрам в подготовленном запросе к базе данных. Этот метод позволяет избежать SQL инъекций и улучшить производительность запросов.
Механика работы метода bind() заключается в том, что он принимает три параметра: тип данных, имя параметра и значение. Тип данных указывает, какой тип данных будет передан в запросе (например, строка, целое число и т. д.). Имя параметра используется для обращения к параметру в запросе. Значение представляет собой фактическое значение, которое будет привязано к параметру.
Пример использования метода bind() в подготовленном запросе к базе данных:
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = :id"); $stmt->bindParam(':id', $id, PDO::PARAM_INT); $id = 1; $stmt->execute();
В данном примере мы подготавливаем запрос на выборку данных из таблицы пользователей, где id равен заданному значению. Мы используем метод bindParam() для привязки значения $id к параметру :id как целое число.
Таким образом, метод bind() позволяет безопасно передавать данные в запросы к базе данных и защищает от возможных атак SQL инъекций. Он также упрощает работу с подготовленными запросами и повышает производительность при многократном выполнении одного и того же запроса с разными значениями.