Last active
August 29, 2015 14:05
-
-
Save AlexKotel/f93a514129ca5ac55829 to your computer and use it in GitHub Desktop.
Extract method from object: x.y(z) -> y(x,z)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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