Func
Функции
Язык программирования не может обойтись без механизма многократного использования кода программы. Такой механизм обеспечивается процедурами или функциями. В JavaScript функция выступает в качестве одного из основных типов данных. Одновременно с этим в JavaScript определен объект Function.
В общем случае любой объект JavaScript определяется через функцию. Для создания объекта используется конструктор, который в свою очередь вводится через Function. Таким образом, с функциями в JavaScript связаны следующие ключевые вопросы:
Именно эти вопросы мы и рассмотрим в данном разделе.
Функция - тип данных
Определяют функцию при помощи ключевого слова function:
function f_name(arg1,arg2,...)
{
/* function body */
}
Здесь следует обратить внимание на следующие моменты. Во-первых, function определяет переменную f_name. Это переменная имеет тип "function":
document.write("Тип переменной f_name:"+typeof(f_name);
function f_name()
{
/* function body */
}
document.write("Тип переменной f_name:"+typeof(f_name));
Во-вторых, этой переменной присваивается значение:
document.write("Значение i:"+i.valueOf());
document.write("Значение f_name:"+f_name.valueOf());
var i=10;
function f_name(a)
{
if(a>=0) return true; else return false;
}
document.write("Значение переменной f_name:"+i.valueOf()+"
");
document.write("Значение переменной f_name:"+f_name.valueOf()+"
");
В данном случае метод valueOf() применяется как к числовой переменной i, так и к f_name. По этой причине функции можно назначить синоним путем присваивания ее значения другой переменной:
function f_name(a)
{
if(a>=0) return true; else return false;
}
document.write("Значение переменной f_name:"+f_name(1)+"
");
b = f_name;
document.write("Значение переменной b:"+b(1)+"
");
function f_name(a)
{
if(a>=0) return true; else return false;
}
document.write("Значение переменной f_name:"+f_name(1)+"
");
b = f_name;
document.write("Значение переменной b:"+b(1)+"
");
Совершенно очевидно, что если функцию можно присвоить переменной, то ее можно передать и в качестве аргумента другой функции. Все это усиливается при использовании функции eval(), которая позволяет реализовать отложенное исполнение JavaScript-кода. Отложенное исполнение - это возможность изменения программы по ходу ее исполнения. Типичным использованием eval() является сокращение кода за счет генерации однотипных строк:
for(i=0;i
{
eval("document.write('kuku"+i+"<br>')");
}
Результат исполнения кода:
for(i=0;i')");
}
Если бы мы кодировали "в лоб", то пришлось бы написать пять строк кода. Данный подход был использован в разделе "Изменение картинки" для инициирования массивов картинок, имена которых построены по принципу индексации ячеек таблицы.
начало страницы
Функция - объект
У любого типа данных JavaScript существует объектовая "обертка" - wrapper, которая позволяет применять методы типов данных к этим переменным и литералам, а также получать значения их свойств. Например, длина строки символов определяется свойством length. Аналогичная "обертка" есть и у функций - объект Function.
Например, увидеть значение функции можно не только при помощи метода valueOf(), но и используя метод toString():
function f_name(x,y)
{
return x-y;
}
document.write(f_name.toString()+"<br>");
Результат распечатки:
function f_name(x,y)
{
return x-y;
}
document.write(f_name.toString()+"
");
Свойства функции доступны для программиста только тогда, когда они вызываются внутри функции. При этом обычно имеют дело с массивом аргументов функции (arguments[]), его длиной (length), именем функции, вызвавшей данную функцию (caller)и прототипом (prototype).
Рассмотрим пример использования списка аргументов функции и его длину:
function my_sort()
{
a = new Array(my_sort.arguments.length);
for(i=0;i<my_sort.arguments.length;i++)
a[i] = my_sort.arguments[i];
b = a.sort();
return b;
}
b = my_sort(9,5,7,3,2)
for(i=0;i<b.length;i++)
document.write("b["+i+"]="+b[i]+"<br>");
Результат исполнения:
function my_sort()
{
a = new Array(my_sort.arguments.length);
for(i=0;i");
Если функция может быть вызвана из различных других функций, то в этом случае используется свойство caller:
function slave()
{
document.write(slave.caller+"
");
return slave.caller;
}
function master1()
{
slave();
}
function master2()
{
slave();
}
...
master1();
master2();
Результат исполнения двух последних строк:
function slave()
{
document.write(slave.caller+"
");
return slave.caller;
}
function master1()
{
slave();
}
function master2()
{
slave();
}
master1();
master2();
Еще одним свойством объекта Function является prototype, но это общее свойство всех объектов, поэтому и обсуждать его мы будем в контексте типа данных Object. Упомянем только о конструкторе объекта Function:
f = new Function(arg_1,...,arg_n, body)
Здесь f - это объект класса Function. Его можно использовать и как обычную функцию. Конструктор используют для получения безымянных функций, которые назначают или переопределяют методы объектов. Здесь мы вплотную подошли к вопросу конструирования объектов. Дело в том, что переменные внутри функции можно рассматривать в качестве ее свойств, а функции - методов:
function Rectangle(a,b,c,d)
{
this.x0 = a;
this.y0 = b;
this.x1 = c;
this.y1 = d;
this.area = new Function("return Math.abs(this.x0-this.x1)*Math.abs(this.y0-this.y1)");
this.perimeter = new Function("return (Math.abs(this.x0-this.x1)+Math.abs(this.y0-this.y1))*2");
}
c = new Rectangle(0,0,100,100);
document.write(c.area());
Результат исполнения:
function Rectangle(a,b,c,d)
{
this.x0 = a;
this.y0 = b;
this.x1 = c;
this.y1 = d;
this.area = new Function("return Math.abs(this.x0-this.x1)*Math.abs(this.y0-this.y1)");
this.perimeter = new Function("return (Math.abs(this.x0-this.x1)+Math.abs(this.y0-this.y1))*2");
}
c = new Rectangle(0,0,100,100);
document.write(c.area()+"
");
Обратите внимание еще на одну особенность - ключевое слово this. Оно позволяет сослаться на текущий объект, в рамках которого происходит исполнение JavaScript-кода. В данном случае это объект c класса Rectangle.