Comments 42
Не понимаю какой смысл писать
вместо
в чем смысл и почему этому надо радоваться, как ребенок?
var amazing = bind(returnFoo, context);
вместо
var amazing = returnFoo.bind(context);
в чем смысл и почему этому надо радоваться, как ребенок?
+21
Похоже, кто-то не понял смысла статьи.
+2
и не он один.
Как это рабоает — понятно. А вот что это дает — вообще осознаваемо.
Как это рабоает — понятно. А вот что это дает — вообще осознаваемо.
+5
Просто неочевидный пример. Вот более частый кейс:
Т.е. простой вызов функции _toString() используется вместо:
и
что весьма удобнее
var _toString = Function.prototype.call.bind(Object.prototype.toString);
_toString({}); // "[object Object]"
_toString(window); // "[object Window]"
_toString([]); // "[object Array]"
Т.е. простой вызов функции _toString() используется вместо:
Object.prototype.toString.call( [] )
и
var _toString = Object.prototype.toString
_toString.call( [] )
что весьма удобнее
+5
UFO just landed and posted this here
И всё равно в какой-то момент я потерял контекст происходящего.
Не думаю, что стоит использовать такие трюки в обычном коде.
Внутри библиотеки — возможно, но в основном коде я бы не стал.
Буду опять перечитывать до полного понимания.
Не думаю, что стоит использовать такие трюки в обычном коде.
Внутри библиотеки — возможно, но в основном коде я бы не стал.
Буду опять перечитывать до полного понимания.
+6
Именно поэтому я написал в начале поста дисклеймер.
Речь не о том, чтобы использовать такие приемы в продакшне. Для меня это была неплохая пища для размышлений, еще один повод подробнее изучить парадигму функционального программирования. Такие вещи неплохо контрастируют с бытовым повседневным программированием. Именно поэтому я решил перевести оригинальный пост и опубликовать его тут.
Речь не о том, чтобы использовать такие приемы в продакшне. Для меня это была неплохая пища для размышлений, еще один повод подробнее изучить парадигму функционального программирования. Такие вещи неплохо контрастируют с бытовым повседневным программированием. Именно поэтому я решил перевести оригинальный пост и опубликовать его тут.
+5
Этот bind давно и повсюду есть и используется:
jQuery: api.jquery.com/jQuery.proxy/
dojo: dojotoolkit.org/reference-guide/1.7/dojo/hitch.html
Эта штука чаще всего нужна когда ты хочешь подвесить функцию, юзающую контекст из this (метод класса) на событие, чтобы при обработке события этот же контекст остался. Задача похожа на то, что часто еще решают с помощью var that = this.
Это уже давно и повсеместно в продакшне.
jQuery: api.jquery.com/jQuery.proxy/
dojo: dojotoolkit.org/reference-guide/1.7/dojo/hitch.html
Эта штука чаще всего нужна когда ты хочешь подвесить функцию, юзающую контекст из this (метод класса) на событие, чтобы при обработке события этот же контекст остался. Задача похожа на то, что часто еще решают с помощью var that = this.
Это уже давно и повсеместно в продакшне.
+2
api.jquery.com/jQuery.proxy/ это ДА bind jQuery.proxy
0
habrahabr.ru/post/199456/#comment_6924098
jQuery.proxy внутри себя не использует нативный bind. Зачем использовать весьма убогий библиотечный метод, если есть нативная альтернатива?
jQuery.proxy внутри себя не использует нативный bind. Зачем использовать весьма убогий библиотечный метод, если есть нативная альтернатива?
+1
Например потому что нативной альтернативы нет в IE <= 8
0
А в чем принципиальная разница их какой именно библиотеки использовать этот bind?
0
В том, что при использовании полифилов, библиотечная функция будет использоваться только в случае отсутствия такой нативной функции. Т.е. в вашем случае, библиотечная реализация bind (которая, к стати в es5-shim сделана лучше, чем в jQuery) будет использоваться только в IE8, а в остальных браузерах будет использоваться нативная функция.
0
Возможно я буду резковат, но «метод» — обычная перестановка. Практической пользы я не могу придумать, а вот трудности уже перед глазами.
ИМХО, это не изящный сниппет, а головная боль на стадии поддержки.
ИМХО, это не изящный сниппет, а головная боль на стадии поддержки.
+6
В Lua круче сделано, там 2 формата вызова методов
obj:func(param1, param3)
тогда в this попадет obj
а можно
obj.func(obj2, param1, param3)
тогда в this попадет obj2
obj:func(param1, param3)
тогда в this попадет obj
а можно
obj.func(obj2, param1, param3)
тогда в this попадет obj2
0
Завсегда юзал для себя свой бинд вот такого вида. Работает ну точно так же как результат в статье, за исключение того что заведомо писался так, чтобы не изменять прототип Function (ну и ещё доп аргументы замыкает). Согласен с первым комментарием короче я.
function bind (context, method) {
var prefix = Array.prototype.slice.call(arguments,2);
return function(){
return method.apply(context, prefix.concat(Array.prototype.slice.call(arguments)));
}
}
0
А где в статье что-то меняет прототип функции?
0
«JavaScript-шаблоны» — бесподобная книга ;-)
0
Радует что вы не добавляли это в прототип функции как шим. Я бы все-таки называл функцию по другому, ведь так или иначе программист севший работать с вашим кодом ожидает что bind ведет себя по спецификации, так что я бы не спешил повсеместно это употреблять.
+1
Ремарочка: неужели вы, садясь разбирать код другого программиста, действительно ждете что его функции будут работать по спецификации? Нет, ну правда?
-2
Да, я именно этого и жду, ибо если я буду лазить в каждый подобный косяк смотря что там и как делают, я буду половину своего времени тратить на «чисто посмотреть а что же делает функция аналогичная спецификации». А это простите никому не интересно. И если функция работает как-то по особому я жду отражения этого в документации.
И по моему мои слова не есть открытие для нормальных проектов где работает не 1 человек и переодически вливаются новые
И по моему мои слова не есть открытие для нормальных проектов где работает не 1 человек и переодически вливаются новые
0
Ну вам повезло работать исключительно в нормальных проектах, иначе вы бы прочувствовали всю ошибочность и времезатратность подхода, который предписывает по умолчанию верить в ответвтенность предыдущего разработчика.
0
Т.е. вы не используете встроенный в движок браузера и весьма оптимизированный Function.prototype.bind только из-за того, что когда-то не во всех браузерах был этот метод?
0
На мой взгляд, перед шагом
неплохо бы добавить ещё один — эквивалентный переход от
к
Без него непонятно, что происходит при вызове bind().
// Немного надоедает использовать .call каждый раз. Может воспользоваться bind?
// Точно! Давайте привяжем функцию call к контексту slice.
slice = Function.prototype.call.bind(Array.prototype.slice);
неплохо бы добавить ещё один — эквивалентный переход от
// Но мы можем использовать apply и call, они позволяют нам передавать нужный контекст
slice.call([1,2,3], 0, 1); // => [1]
к
Function.prototype.call(slice, [1,2,3], 0, 1); // => [1]
Без него непонятно, что происходит при вызове bind().
+1
Спасибо тебе, добрый человек. Без bind никак не мог решить задачу с addEventListener (и remove в перспективе). А с ним смог так:
var foo = {
prop: 0,
bar: function(){
console.log(++this.prop);
},
init: function(){
this.bar = this.bar.bind(this);
document.addEventListener("click", this.bar);
}
};
foo.init();
foo.bar();
0
Может быть вызов обработчика в init лучше оформить в виде классического callback-а, поскольку перезапись this.bar в данном случае смысла не имеет:
init: function(){
var callback = this.bar.bind(this);
document.addEventListener("click", callback);
0
Любопытно, кстати, что следующий, казалось бы, эквивалентный вариант привязки контекста уже не работает, так как вызов bar с bind срабатывает уже внутри addEventListener в глобальном контексте:
bar: (function(){
console.log(++this.prop);
}).bind(this),
init: function(){
document.addEventListener("click", this.bar);
}
0
до меня долго доходило, почему мы в call биндим функцию, но потом понял, что для Array.prototype.slice это и есть функция к которой будет применяться call… по сути мы жестко привязываем call на эту функцию и возвращаем значение в переменную. получается для выражения: slice = Function.prototype.call.bind(Array.prototype.slice); на пальцах можно объяснить так: в переменную slice верни функцию call которая будет вызываться в контексте Array.prototype.slice (так как мы ее забиндили для функции call и теперь внутри функции call — this это Array.prototype.slice). Надеюсь может кому-то поможет в осознании того, что написал автор, хотя прочитав сейчас то, что написал засомневался =)
0
Sign up to leave a comment.
Bind, Call и Apply в JavaScript