Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.149.251.155] |
|
Страницы: (2) [1] 2 все ( Перейти к последнему сообщению ) |
Сообщ.
#1
,
|
|
|
Друзья приветствую вас, есть вопрос: чем отличается Function.prototype.bind от Function.prototype.call или apply?
немного покодив пришел к выводу, что bind не просто возвращает функцию, которая вызывает другую функцию в нужном контексте, например: var Person = { getName: function(){ return this.name; } }; var createPerson = function(specs){ return { getName1: function(){ return Person.getName.call(specs); }, getName2: Person.getName.bind(specs) }; }; var gregory = createPerson({name: 'Gregory'}); console.log(gregory.getName1()); // Gregory console.log(gregory.getName2()); // Gregory на первый взгляд результат одинаковый, но вот в плане расхода памяти вызов call жрет больше чем bind, вы спросите как я понял это? да все просто я провел тесты! в связи с этим у меня возник этот вопрос, что там такого в bind, почему он расходует меньше памяти? |
Сообщ.
#2
,
|
|
|
это я к тому что есть ли профит от Function.prototype.call, если bind выполнит тоже без проблем и судя по тестам еще и меньше памяти сожрет?
ну я имею ввиду заменить вызов Person.getName.call(specs); на Person.getName.bind(specs)(); |
Сообщ.
#3
,
|
|
|
ждём "гениальных" идей.
|
Сообщ.
#4
,
|
|
|
Цитата K313 @ ждём "гениальных" идей. гениальная идея уже озвучена! юзать bind вместо call остается понять в чем секрет bind, мои изучения вкладки Memory в консоли гугл хром показали, что при bind размер разделов closure и system/context меньше чем при вызове call. пс. надо потестить Function.prototype.apply чето про него забыл, где то читал, что вроде Function.prototype.call является оберткой apply Добавлено потестил c Function.prototype.apply результат почти одинаковый, возможно чуть меньше по отношению с Function.prototype.call. |
Сообщ.
#5
,
|
|
|
у bind и call разные предназначения, как я понял.... и разные производимые действия. Ты опять всё в одну кучу перемешал
|
Сообщ.
#6
,
|
|
|
Цитата K313 @ у bind и call разные предназначения, как я понял.... и разные производимые действия. Ты опять всё в одну кучу перемешал насколько разные? я понимаю что bind юзается там где требуется предавать функцию в нужном контексте, или юзать для частичного применения, а call и apply - вызов функции в нужном контексте. но потом то функцию, которую возвращает bind можно вызвать, что я и делаю. проверил тесты производительности на jsPerf.com и получил недвусмысленые результаты: [attach=#0][/attach] производительность bind выше чем call и apply, а расход памяти как я уже писал выше у bind меньше! Вывод? хотя это может тока на моем компе так , по идее bind должен быть и медленее и занимать больше памяти я смотрел пример кастомной реализации bind для ES3 (поскольку ее там нет) и она юзает замыкания, что должно сказаться на расходе памяти, а вот как она реализована в стандарте ES5 (Google Chrome 61 V8) я хз, но результаты тестов говорят за себя. можешь сам потестить jsPerf.com Кстати надо проверить кастомную версию bind. Добавлено протестил с кастомной версией bind и результаты подтвердились расход памяти значительно превысил то отношению к call и apply, думаю что скорее всего хром жаваскрипт движок V8 как то оптимизирует bind Прикреплённый файлjsperf.jpg (72,25 Кбайт, скачиваний: 533) |
Сообщ.
#7
,
|
|
|
у тебя getName1 и getName2 - это кажись одно и тоже, просто первый это кастомный, а второй встроенный приёмы.
|
Сообщ.
#8
,
|
|
|
Цитата K313 @ у тебя getName1 и getName2 - это кажись одно и тоже, просто первый это кастомный, а второй встроенный приёмы. ну да так и есть, я что об этом спрашивал? call это вызов функции в контексте, а bind - связывание функции с контекстом. я пытаюсь тебе донести, что через bind памяти жрет меньше Цитата Cfon @ хотя это может тока на моем компе так , по идее bind должен быть и медленее и занимать больше памяти |
Сообщ.
#9
,
|
|
|
а, ну да, просто я уже запутался в твоих схемах
короче я тут выпендриваюсь потому что ты хочешь Цитата Cfon @ это я к тому что есть ли профит от Function.prototype.call, если bind выполнит тоже без проблем и судя по тестам еще и меньше памяти сожрет? ну я имею ввиду заменить вызов а я пытаюсь тебе показать, что это разные вещи function f( ) { return this.user; } f.user = "I'm result!" alert( f( ) ); alert( f.call( { user: 'call Cfon' } ) ); alert( f.call( f ) ); alert( f.bind( { user: 'bind Cfon' } ) ); alert( f.bind( { user: 'bind after call Cfon' } )( ) ); что потом после твоиз замен, что-то может работать не так как ты ожидал кажися так. Добавлено а на счёт памяти, посмотри в своих тестах, при .bind( ... ) сохраняется в памяти текущий [[scope]] от вызова createPerson или нет? Если нет - вот тебе и экономия рамяти Добавлено Цитата Cfon @ но потом то функцию, которую возвращает bind можно вызвать, что я и делаю. а это я пропустил,... ты это оказываеся и без меня знаешь |
Сообщ.
#10
,
|
|
|
Цитата K313 @ а я пытаюсь тебе показать, что это разные вещи function f( ) { return this.user; } f.user = "I'm result!" alert( f( ) ); alert( f.call( { user: 'call Cfon' } ) ); alert( f.call( f ) ); alert( f.bind( { user: 'bind Cfon' } ) ); alert( f.bind( { user: 'bind after call Cfon' } )( ) ); что потом после твоиз замен, что-то может работать не так как ты ожидал кажися так. Добавлено Цитата Cfon @ но потом то функцию, которую возвращает bind можно вызвать, что я и делаю. а это я пропустил,... ты это оказываеся и без меня знаешь обижаешь дружище! их назначение и применения я давно изучил я же гений забыл? Цитата K313 @ Добавлено а на счёт памяти, посмотри в своих тестах, при .bind( ... ) сохраняется в памяти текущий [[scope]] от вызова createPerson или нет? Если нет - вот тебе и экономия рамяти вот я и спрашиваю у тех кто знает кухню движка JS например Google Chrome V8 что да как там с bind сам я конечно смотрел на расход памяти по вкладке Memory консоли Google Chrome, но пока увидел то что писал выше в посте №1 повторюсь меня интересует почему при bind расход памяти меньше чем при call или apply? козе понятно что у bind, call разное назначение, а мне гению тем более понятно |
Сообщ.
#11
,
|
|
|
Цитата Cfon @ обижаешь дружище! их назначение и применения я давно изучил я же гений забыл? я подумал, что пока ты о великом думал, какую-то мелочь упустил Цитата Cfon @ почему при bind расход памяти меньше чем при call или apply? может потому что при .call( ) у тебя замыкание, то есть текущий [[scope]] от createPerson нужно в памяти оставлять, а для .bind( ) не нужно??? |
Сообщ.
#12
,
|
|
|
Цитата K313 @ Цитата Cfon @ почему при bind расход памяти меньше чем при call или apply? может потому что при .call( ) у тебя замыкание, то есть текущий [[scope]] от createPerson нужно в памяти оставлять, а для .bind( ) не нужно??? по идее bind Person.getName.bind(specs); это тоже что и function(){ return Person.getName.call(specs); } вот пример кастомного бинда (полифила для ES3) Function.prototype.custom_bind = function (thisArg) { var fn = this, slice = Array.prototype.slice, args = slice.call(arguments, 1); return function () { return fn.apply(thisArg, args.concat(slice.call(arguments))); }; }; поэтому я не понял почему при bind расход памяти больше, хотя как я уже писал выше если заменить bind ES5 на этот custom_bind, то расход памяти сразу увеличивается, что говорит о том что скорее всего bind es5 как то оптимизируется |
Сообщ.
#13
,
|
|
|
Цитата Cfon @ при bind расход памяти больше в смысле - меньше Цитата Cfon @ это тоже что и при .call он у тебя выполняется, когда ты вызываешь console.log(gregory.getName1()); // Gregory а .bind у тебя выполняется ещё при вызове var gregory = createPerson({name: 'Gregory'}); чуешь разницу? поэтому я думаю что для .bind замыкание не нужно, в памяти достаточно сохранять только переданный .bind-у объект. Добавлено прежняя аватарка была круче |
Сообщ.
#14
,
|
|
|
Цитата K313 @ Цитата Cfon @ в смысле - меньше при bind расход памяти больше опечатался, конечно же меньше я запускал свои тесты в хроме и делал heap snapshot, потом сравнивал и размер при bind был 4.7Mb, при call - 5.5Mb. Цитата K313 @ Цитата Cfon @ это тоже что и при .call он у тебя выполняется, когда ты вызываешь console.log(gregory.getName1()); // Gregory а .bind у тебя выполняется ещё при вызове var gregory = createPerson({name: 'Gregory'}); чуешь разницу? поэтому я думаю что для .bind замыкание не нужно, в памяти достаточно сохранять только переданный .bind-у объект. ок а почему тогда при кастомном бинде памяти жрет больше чем при call? если следовать твоему предположению она не должна жрать больше памяти или я чего не понял? Цитата K313 @ Добавлено прежняя аватарка была круче |
Сообщ.
#15
,
|
|
|
Цитата Cfon @ ок а почему тогда при кастомном бинде памяти жрет больше чем при call? наверно потому что кастомный .bind тоже на замыкании строится, да ещё похлеще твоего .call в createPerson Добавлено а так, х его знает, это всё предположения |