Skip to content

Instantly share code, notes, and snippets.

@AlexKotel
Last active August 29, 2015 14:05
Show Gist options
  • Save AlexKotel/f93a514129ca5ac55829 to your computer and use it in GitHub Desktop.
Save AlexKotel/f93a514129ca5ac55829 to your computer and use it in GitHub Desktop.
Extract method from object: x.y(z) -> y(x,z)
#Extract method from object
# Положим в ПЕРЕМЕННУЮ slice ФУНКЦИЮ slice из прототипа объекта Array
slice = Array.prototype.slice
# Используем call или apply, чтобы предоставить контекст (this) для функции slice
slice.call([1,2,3], 0, 1) # => [1]
slice.apply([1,2,3], [0,1]) # => [1]
# Т.к. call - это метод объекта Function, это значит, что контекстом метода call является вызывающая его функция
# в нашем примере это функция slice
# Следовательно, рассуждая таким образом, мы можем задать контекст выполнения для самого метода call
Function.prototype.call.call(slice, [1,2,3], 0, 1) # => [1]
# В этой строке мы вызываем ФУНКЦИЮ call (Function.prototype.call), через .call с аргументами ([1,2,3], 0, 1)
# и контекстом вызова slice.
# Выходит, что для ФУНКЦИИ call slice является вызывающим объектом (this),
# [1,2,3] - первый аргумент, который функция call сделает контекстом функции slice и передаст ей аргументы 0 и 1
# Немного надоедает использовать .call каждый раз. Может воспользоваться bind?
# Точно! Давайте привяжем функцию call к контексту slice.
call = Function.prototype.call
slice = call.bind(slice)
# Теперь в ПЕРЕМЕННОЙ slice лежит ФУНКЦИЯ call, у которой this - это функция slice
# (т.е. slice(context, args...) === call.call(slice, context, args...)
# Теперь slice использует первый аргумент в качестве контекста
slice([1,2,3], 0, 1) # => [1]
# Давайте проделаем с самим bind то же, что мы делали со slice
bind = call.bind(Function.prototype.bind)
# Таким образом:
extMethod = (method) ->
call = Function.prototype.call
call.bind(method)
# Использование
slice = extMethod(Array.prototype.slice)
slice([1,2,3], 0, 1) # => [1]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment