Статьи

Функции Javascript — Часть 3


В этом посте я собираюсь поэкспериментировать с еще несколькими способами вызова функций в javascript.
В моем предыдущем посте 
функции Javascript — часть 2  я подробно описал несколько способов вызова функций.


В отличие от многих других языков, функции JavaScript — это больше, чем просто функции.
Они тоже объекты. И поскольку функции, будучи объектом, могут иметь больше функций, определенных для них, javascript позволяет нам иметь две довольно полезные функции, которые можно использовать для вызова функций.

Каждая функция в javascript может быть вызвана по имени и переданным параметрам.
Однако контекст, в котором вызывается функция, может каждый раз отличаться.

Какие?
Контекст? Теперь, где это вошло в картину?


Ну, если бы я определил контекст, я бы сказал, что это не что иное, как значение this в выполняемой функции.
Кажется довольно просто, а?


Но почему-то значение «this» не так легко понять при программировании на javascript.
Это потому, что «это» — это не обычное «это», которое вы видите на других языках, таких как Java. Для кого-то вроде меня, который вмешивался в концепции жесткого кода и упс, то, как «это» использовалось в javascript, было довольно неуловимым в начале.

Я не буду много говорить об «этом» в сегодняшнем посте, однако есть кое-что, что нам нужно знать, прежде чем мы сможем проверить 2 новых способа вызова функций в javascript.


это то, что вы должны знать!
<вставить злой смех здесь>


Всякий раз, когда функция вызывается в javascript, и нет объекта, который является ее инициатором, оконный объект считается вызывающим по умолчанию.


Кроме того, при определении объектов, которые не являются членами других объектов, объекты считаются членами объекта по умолчанию — объекта окна.


Ну, две приведенные выше строки довольно просты.
Но давайте посмотрим, как эти простые мелочи могут сделать поведение кода непредсказуемым при программировании, если вы не будете осторожны с кодом.


Предположим, у нас есть следующая функция, определенная в нашем скрипте

var v={a:10};
  v.fun4=function(){
   alert("fun4 "+ this);
   fun5();
  }

function fun5(){
   alert("fun5" + this);
  }

v.fun4();


То, что я сделал здесь, довольно просто.
Я создал объект ‘v’ со свойством ‘a’ и функцией fun4 (). fun4 () предупреждает сообщение и затем вызывает fun5 (). Запустите этот код и посмотрите, что произойдет. Как видите, первое предупреждение указывает на то, что значением ключевого слова ‘this’ в функции fun4 является объект (в нашем случае это ‘v’. Вы можете проверить это, напечатав значение va). Но второе предупреждение указывает, что значением this является не объект v, а объект окна по умолчанию.


Если вы не знакомы с javascript, вы можете быть озадачены, может быть, на какое-то время, прежде чем концепция начнет проявлять себя.


Как видите, при объявлении функции fun5 () она не объявляется как функция какого-либо объекта.
Следовательно, эта функция неявно является функцией объекта окна. Функции, объявленные в объекте window, являются глобальными и могут вызываться любой другой функцией, что и делает наша fun4 (). Следовательно, контекстом по умолчанию функции fun5 () является объект окна, который является значением нашего ключевого слова this.

Но что, если вы хотите, чтобы значением ‘this’ был объект ‘v’ в fun5?
Чем ты занимаешься?

Что ж, если вы думаете, что можете просто заменить строку fun5 () на this.fun5 (), это, мой друг, просто не сработает.
Это потому, что функция fun5 () не является функцией объекта this в fun4 ().



Тем не менее, есть способ сделать это.
Функции call () и apply () в javascript могут быть использованы для помощи именно в этом сценарии. Эти функции используются для установки контекста функции, что отражается в значении ключевого слова this.


В следующем фрагменте кода мы собираемся объявить еще 2 функции для нашего объекта v.
И 2 глобальные функции на объекте окна.


v.fun6 () вызывает глобальную функцию fun7 () с помощью функции call ().


v.fun8 () вызывает глобальную функцию fun9 () с помощью функции apply ().

v.fun6=function(){
   alert("fun6 "+ this);
   fun7.call(this,'ryan');
  }
  
  function fun7(arg){
   alert("fun7" + this + " arg : "+ arg);
  }
  
  v.fun8=function(){
   alert("fun8 "+ this);
   fun9.apply(this,['ryan']);
  }
  
  function fun9(arg){
   alert("fun9" + this + " arg : "+ arg);
  }
  
  v.fun6();
  v.fun8();


Как видно, глобальные функции также получают параметр.
Синтаксис call () и apply () очень похожи. Первый аргумент обеих этих функций используется в качестве контекста, в котором должна вызываться фактическая функция.


Метод call () может иметь много аргументов после первого аргумента, так что каждый аргумент становится аргументом, который должен быть передан фактической функции.

Второй аргумент функции apply () принимает массив значений, которые должны быть переданы в качестве аргументов действительной функции.


Запустите код и убедитесь, что значение ключевого слова this теперь правильно используется в глобальных функциях.

Одним из следствий такого рода техники является то, что у вас может быть несколько глобальных функций, каждая из которых выполняет одну общую задачу.
И вы можете иметь несколько объектов, принадлежащих к разным классам, которые вызывают эти глобальные функции, используя свой собственный контекст, тем самым уменьшая избыточность существующих функций.


Это все на данный момент.
Мы сделаем еще несколько экспериментов в следующем посте. :>

Счастливого программирования 🙂

Подписание