<b> // Теперь вызвать self как метод объекта о со всеми аргументами </b>
<b> return self.apply(о, args);</b>
<b> };</b>
<b> };</b>
<b>}</b>
Обратите внимание, что функция, возвращаемая этим методом
<b>bind(),</b>
является замыканием, использующим переменные
<b>self</b>
и
<b>boundArgs,</b>
объявленные во внешней функции, которые остаются доступными вложенной функции даже после того, как она будет возвращена внешней функцией и вызвана из-за пределов внешней функции.
Метод
<b>bind(),</b>
определяемый стандартом ECMAScript 5, имеет некоторые особенности, которые невозможно реализовать в ECMAScript 3. Прежде всего, настоящий метод
<b>bind()</b>
возвращает объект функции, свойство
<b>length</b>
которой установлено в соответствии с количеством параметров связываемой функции, минус количество связанных аргументов (но не меньше нуля). Во-вторых, метод
<b>bind(</b>
) в ECMAScript 5 может использоваться для частичного применения функций-конструкторов. Если функцию, возвращаемую методом
<b>bind(),</b>
использовать как конструктор, значение
<b>this</b>
, переданное методу
<b>bind(),</b>
игнорируется, и оригинальная функция будет вызвана как конструктор, с уже связанными аргументами, если они были определены. Функции, возвращаемые методом
<b>bind(),</b>
не имеют свойства prototype (свойство prototype обычных функций нельзя удалить), и объекты, созданные связанными функциями-конструкторами, наследуют свойство prototype оригинального, несвязанного конструктора. Кроме того, с точки зрения оператора
<b>instanceof</b>
связанные конструкторы действуют точно так же, как несвязанные конструкторы.
8.7.5. Метод toString()
Подобно другим объектам в языке JavaScript, функции имеют метод
<b>toString()</b>
. Спецификация ECMAScript требует, чтобы этот метод возвращал строку, следующую синтаксису инструкции объявления функции. На практике большинство (но не все) реализаций метода
<b>toString()</b>
возвращают полный исходный текст функции. Для встроенных функций обычно возвращается строка, содержащая вместо тела функции текст «[native code]» или аналогичный.
8.7.6. Конструктор Function()
Функции обычно определяются с помощью ключевого слова
<b>function</b>
либо в форме инструкции объявления функции, либо в форме выражения-литерала. Однако функции могут также определяться с помощью конструктора
Function().
Например:
<b>var f = new Function("x", "у", "return x*y;");</b>
Эта строка создаст новую функцию, которая более или менее эквивалентна функции, объявленной с помощью более привычного синтаксиса:
<b>var f = function(x, у) { return х*у; }</b>
Конструктор
<b>Function()</b>
принимает произвольное число строковых аргументов. Последний аргумент должен содержать текст с телом функции; он может включать произвольное число инструкций на языке JavaScript, разделенных точкой с запятой. Все остальные аргументы конструктора интерпретируются как имена параметров функции. Чтобы создать функцию, не имеющую аргументов, достаточно передать конструктору всего одну строку - тело функции.
Примечательно, что конструктору
<b>Function()</b>
не передается никаких аргументов, определяющих имя создаваемой функции. Подобно литералам функций, конструктор
<b>Function()</b>
создает анонимные функции.
Есть несколько моментов, связанных с конструктором
<b>Function(),</b>
о которых следует упомянуть особо:
• Конструктор
<b>Function()</b>
позволяет динамически создавать и компилировать функции в процессе выполнения программы.
• При каждом вызове конструктор
<b>Function()</b>
выполняет синтаксический анализ тела функции и создает новый объект функции. Если вызов конструктора производится в теле цикла или часто вызываемой функции, это может отрицательно сказаться на производительности программы. Напротив, вложенные функции и выражения определения функций внутри циклов не компилируются повторно.
• И последний, очень важный момент: когда функция создается с помощью конструктора
<b>Function(),</b>
не учитывается лексическая область видимости - функции всегда компилируются как глобальные функции, что наглядно демонстрирует следующий фрагмент:
<b>var scope = "глобальная";</b>
<b>function constructFunction() { </b>
<b> var scope = "локальная";</b>
<b> return new Function("return scope”); // Здесь не используется</b>
<b> // локальная область видимости!</b>
<b>} ;</b>
<b>// Следующая строка вернет "глобальная", потому что функция, возвращаемая </b>
<b>// конструктором Function(), является глобальной. </b>
<b>constructFunction()(); // => "глобальная"</b>
Точнее всего конструктор
<b>Function()</b>
соответствует глобальной версии
<b>eval()</b>
(раздел 4.12.2), которая определяет новые переменные и функции в своей собственной области видимости. Вам редко придется использовать этот конструктор в своих программах.
8.7.7. Вызываемые объекты
В разделе 7.11 мы узнали, что существуют объекты, «подобные массивам», которые не являются настоящими массивами, но во многих случаях могут интерпретироваться как массивы. Аналогичная ситуация складывается с функциями. Вызываемый объект - это любой объект, который может быть вызван в выражении вызова функции. Все функции являются вызываемыми объектами, но не все вызываемые объекты являются функциями.