Основы работы с пользовательскими функциями в JavaScript
Сейчас мы с вами научимся создавать свои функции, которые затем можно будет использовать подобно стандартным функциям и методам JavaScript. Давайте рассмотрим синтаксис для создания своей функции.
Функция создается с помощью команды function . Далее через пробел следует имя функции, круглые скобки, а затем фигурные скобки, в которых пишется какой-то код:
function func() < // какой-то код >
Давайте посмотрим на каком-нибудь примере. Сделаем функцию с именем func , которая при своем вызове будет выводить алертом восклицательный знак:
function func() < console.log('!'); >
Давайте теперь вызовем нашу функцию. Для этого необходимо написать ее имя и круглые скобки:
function func() < console.log('!'); >// Вызываем нашу функцию: func(); // выведет ‘!’
Можно вызвать нашу функцию несколько раз — в этом случае каждый вызов функции будет выдавать новый алерт:
function func() < console.log('!'); >func(); // выведет ‘!’ func(); // выведет ‘!’ func(); // выведет ‘!’
Функции могут быть вызваны до места своего определения:
func(); // выведет ‘!’ function func() < console.log('!'); >
Сделайте функцию, выводящую в консоль ваше имя.
Сделайте функцию, выводящую в консоль сумму чисел от 1 до 100 .
Общие сведения о пользовательских функций JavaScript
Определяемые пользователем функции (UDF) JavaScript являются новыми в службы Excel в SharePoint. В этой статье предоставляет подробный обзор пользовательских функций JavaScript, в том числе основные сведения о работе в Службы Excel.
Сведения о пользовательских функциях JavaScript для надстроек Office см. в статье Создание пользовательских функций в Excel.
Что такое пользовательских функций
Пользовательские функции (UDF) это функция самостоятельно создать и затем добавить в список доступных функций в Excel при Excel не предоставляет тип функции, которые должны сразу же после установки.
Службы Excel уже позволяет создавать пользовательские функции с помощью управляемого кода, поэтому если вы работали с существующим Службы Excel пользовательских функций, пользовательских функций JavaScript должны быть знакомы вам. Дополнительные сведения о создании определяемых пользователем функций с помощью управляемого кода см. в разделе Функции службы Excel User-Defined.
Пользовательские функции JavaScript
Пользовательские функции JavaScript, пользовательских функций, которые запускаются в браузере на веб-страницу, состоит в книге внедренных Excel. Используйте JavaScript UDF внутри внедренной книги. До тех пор, пока вы работаете с книгой в браузере, можно использовать JavaScript UDF так же, как использовать функции встроенных Excel. При закрытии веб-страницы в JavaScript UDF больше не доступен.
Как работают JavaScript UDF?
Чтобы использовать JavaScript UDF, необходимо иметь возможность изменения содержимого веб-страницы, где внедрить эту книгу. После добавления ссылки к исходному файлу правильные Службы Excel JavaScript, добавьте код JavaScript UDF на страницу. Кроме того прежде чем использовать JavaScript UDF, сначала необходимо зарегистрировать пользовательскую Функцию в Службы вычислений Excel. JavaScript UDF API предоставляет методы для регистрации и отмены регистрации JavaScript UDF.
Когда веб-страница с веб-частью Excel Web Access или внедренной книгой отрисовывается, вы можете вызвать определяемую пользователем функцию JavaScript в книге так же, как и любую другую книгу Excel.
Например имеется функция, которая получает текущий акций для указанного актива. Можно добавить JavaScript UDF на веб-страницу, на котором размещается книги Excel (предполагается, что у вас есть авторские права для веб-страницы), которые использует JavaScript код следующим образом.
function StockInfo(symbol, measure) < var req = new XMLHttpRequest(); req.open('GET', 'http://www.contoso-stock-quotes.com/quote/' + symbol + '/' + measure, false); req.send(null); if (req.status == 200) < return req.responseText; >else < throw new Error(ExcelCalcError.Value); >ewa.BrowserUdfs.add("StockQuote", StockInfo, "Gets a stock quote given a security symbol and measure to return." false, false );
Затем можно назвать JavaScript UDF, StockInfo, в формуле из ячейки внутри Excel Online.
Рис. 1. Определяемая пользователем функция JavaScript, вызываемая в Excel Online
Где можно использовать пользовательские функции JavaScript?
Вы можете создавать и использовать определяемые пользователем функции JavaScript либо в книгах, отображаемых в веб-частях SharePoint Excel Web Access, либо на веб-странице узла с внедренной книгой. Книга должна храниться на Microsoft OneDrive. Основное отличие заключается в том, что определяемые пользователем функции JavaScript, добавляемые в веб-части Excel Web Access, требуют наличия сервера SharePoint. Пользовательские функции JavaScript, добавлена для размещения веб-страницы, внедренной книги требуется только сохранение книги на OneDrive.
Ключевые моменты
- Пользовательские функции JavaScript только live до тех пор, пока они находятся на веб-страницей, отображается. Они не сохраняются после истечения времени жизни веб-страницы, где они были созданы.
- Нельзя выполнять вызовы Службы Excel объектной модели JavaScript из в JavaScript UDF.
См. также
- Службы Excel в SharePoint
- Пользовательские функции служб Excel
Объект функции, NFE
Как мы уже знаем, в JavaScript функция – это значение.
Каждое значение в JavaScript имеет свой тип. А функция – это какой тип?
В JavaScript функции – это объекты.
Можно представить функцию как «объект, который может делать какое-то действие». Функции можно не только вызывать, но и использовать их как обычные объекты: добавлять/удалять свойства, передавать их по ссылке и т.д.
Свойство «name»
Объект функции содержит несколько полезных свойств.
Например, имя функции нам доступно как свойство «name»:
function sayHi() < alert("Hi"); >alert(sayHi.name); // sayHi
Что довольно забавно, логика назначения name весьма умная. Она присваивает корректное имя даже в случае, когда функция создаётся без имени и тут же присваивается, вот так:
let sayHi = function() < alert("Hi"); >; alert(sayHi.name); // sayHi (есть имя!)
Это работает даже в случае присваивания значения по умолчанию:
function f(sayHi = function() <>) < alert(sayHi.name); // sayHi (работает!) >f();
В спецификации это называется «контекстное имя»: если функция не имеет name, то JavaScript пытается определить его из контекста.
Также имена имеют и методы объекта:
let user = < sayHi() < // . >, sayBye: function() < // . >> alert(user.sayHi.name); // sayHi alert(user.sayBye.name); // sayBye
В этом нет никакой магии. Бывает, что корректное имя определить невозможно. В таких случаях свойство name имеет пустое значение. Например:
// функция объявлена внутри массива let arr = [function() <>]; alert( arr[0].name ); // // здесь отсутствует возможность определить имя, поэтому его нет
Впрочем, на практике такое бывает редко, обычно функции имеют name .
Свойство «length»
Ещё одно встроенное свойство «length» содержит количество параметров функции в её объявлении. Например:
function f1(a) <> function f2(a, b) <> function many(a, b, . more) <> alert(f1.length); // 1 alert(f2.length); // 2 alert(many.length); // 2
Как мы видим, троеточие, обозначающее «остаточные параметры», здесь как бы «не считается»
Свойство length иногда используется для интроспекций в функциях, которые работают с другими функциями.
Например, в коде ниже функция ask принимает в качестве параметров вопрос question и произвольное количество функций-обработчиков ответа handler .
Когда пользователь отвечает на вопрос, функция вызывает обработчики. Мы можем передать два типа обработчиков:
- Функцию без аргументов, которая будет вызываться только в случае положительного ответа.
- Функцию с аргументами, которая будет вызываться в обоих случаях и возвращать ответ.
Чтобы вызвать обработчик handler правильно, будем проверять свойство handler.length .
Идея состоит в том, чтобы иметь простой синтаксис обработчика без аргументов для положительных ответов (наиболее распространённый случай), но также и возможность передавать универсальные обработчики:
function ask(question, . handlers) < let isYes = confirm(question); for(let handler of handlers) < if (handler.length == 0) < if (isYes) handler(); >else < handler(isYes); >> > // для положительных ответов вызываются оба типа обработчиков // для отрицательных - только второго типа ask("Вопрос?", () => alert('Вы ответили да'), result => alert(result));
Это частный случай так называемого Ad-hoc-полиморфизма – обработка аргументов в зависимости от их типа или, как в нашем случае – от значения length . Эта идея имеет применение в библиотеках JavaScript.
Пользовательские свойства
Мы также можем добавить свои собственные свойства.
Давайте добавим свойство counter для отслеживания общего количества вызовов:
function sayHi() < alert("Hi"); // давайте посчитаем, сколько вызовов мы сделали sayHi.counter++; >sayHi.counter = 0; // начальное значение sayHi(); // Hi sayHi(); // Hi alert( `Вызвана $ раза` ); // Вызвана 2 раза
Свойство не есть переменная
Свойство функции, назначенное как sayHi.counter = 0 , не объявляет локальную переменную counter внутри неё. Другими словами, свойство counter и переменная let counter – это две независимые вещи.
Мы можем использовать функцию как объект, хранить в ней свойства, но они никак не влияют на её выполнение. Переменные – это не свойства функции и наоборот. Это два параллельных мира.
Иногда свойства функции могут использоваться вместо замыканий. Например, мы можем переписать функцию-счётчик из главы Область видимости переменных, замыкание, используя её свойство:
function makeCounter() < // вместо // let count = 0 function counter() < return counter.count++; >; counter.count = 0; return counter; > let counter = makeCounter(); alert( counter() ); // 0 alert( counter() ); // 1
Свойство count теперь хранится прямо в функции, а не в её внешнем лексическом окружении.
Это хуже или лучше, чем использовать замыкание?
Основное отличие в том, что если значение count живёт во внешней переменной, то оно не доступно для внешнего кода. Изменить его могут только вложенные функции. А если оно присвоено как свойство функции, то мы можем его получить:
function makeCounter() < function counter() < return counter.count++; >; counter.count = 0; return counter; > let counter = makeCounter(); counter.count = 10; alert( counter() ); // 10
Поэтому выбор реализации зависит от наших целей.
Named Function Expression
Named Function Expression или NFE – это термин для Function Expression, у которого есть имя.
Например, давайте объявим Function Expression:
let sayHi = function(who) < alert(`Hello, $`); >;
И присвоим ему имя:
let sayHi = function func(who) < alert(`Hello, $`); >;
Чего мы здесь достигли? Какова цель этого дополнительного имени func ?
Для начала заметим, что функция всё ещё задана как Function Expression. Добавление «func» после function не превращает объявление в Function Declaration, потому что оно все ещё является частью выражения присваивания.
Добавление такого имени ничего не ломает.
Функция все ещё доступна как sayHi() :
let sayHi = function func(who) < alert(`Hello, $`); >; sayHi("John"); // Hello, John
Есть две важные особенности имени func , ради которого оно даётся:
- Оно позволяет функции ссылаться на себя же.
- Оно не доступно за пределами функции.
Например, ниже функция sayHi вызывает себя с «Guest» , если не передан параметр who :
let sayHi = function func(who) < if (who) < alert(`Hello, $`); > else < func("Guest"); // использует func, чтобы снова вызвать себя же >>; sayHi(); // Hello, Guest // А вот так - не cработает: func(); // Ошибка, func не определена (недоступна вне функции)
Почему мы используем func ? Почему просто не использовать sayHi для вложенного вызова?
Вообще, обычно мы можем так поступить:
let sayHi = function(who) < if (who) < alert(`Hello, $`); > else < sayHi("Guest"); >>;
Однако, у этого кода есть проблема, которая заключается в том, что значение sayHi может быть изменено. Функция может быть присвоена другой переменной, и тогда код начнёт выдавать ошибки:
let sayHi = function(who) < if (who) < alert(`Hello, $`); > else < sayHi("Guest"); // Ошибка: sayHi не является функцией >>; let welcome = sayHi; sayHi = null; welcome(); // Ошибка, вложенный вызов sayHi больше не работает!
Так происходит, потому что функция берёт sayHi из внешнего лексического окружения. Так как локальная переменная sayHi отсутствует, используется внешняя. И на момент вызова эта внешняя sayHi равна null .
Необязательное имя, которое можно вставить в Function Expression, как раз и призвано решать такого рода проблемы.
Давайте используем его, чтобы исправить наш код:
let sayHi = function func(who) < if (who) < alert(`Hello, $`); > else < func("Guest"); // Теперь всё в порядке >>; let welcome = sayHi; sayHi = null; welcome(); // Hello, Guest (вложенный вызов работает)
Теперь всё работает, потому что имя «func» локальное и находится внутри функции. Теперь оно взято не снаружи (и недоступно оттуда). Спецификация гарантирует, что оно всегда будет ссылаться на текущую функцию.
Внешний код все ещё содержит переменные sayHi и welcome , но теперь func – это «внутреннее имя функции», таким образом она может вызвать себя изнутри.
Это не работает с Function Declaration
Трюк с «внутренним» именем, описанный выше, работает только для Function Expression и не работает для Function Declaration. Для Function Declaration синтаксис не предусматривает возможность объявить дополнительное «внутреннее» имя.
Зачастую, когда нам нужно надёжное «внутреннее» имя, стоит переписать Function Declaration на Named Function Expression.
Итого
Функции – это объекты.
- name – имя функции. Обычно берётся из объявления функции, но если там нет – JavaScript пытается понять его из контекста.
- length – количество аргументов в объявлении функции. Троеточие («остаточные параметры») не считается.
Если функция объявлена как Function Expression (вне основного потока кода) и имеет имя, тогда это называется Named Function Expression (Именованным Функциональным Выражением). Это имя может быть использовано для ссылки на себя же, для рекурсивных вызовов и т.п.
Также функции могут содержать дополнительные свойства. Многие известные JavaScript-библиотеки искусно используют эту возможность.
Они создают «основную» функцию и добавляют множество «вспомогательных» функций внутрь первой. Например, библиотека jQuery создаёт функцию с именем $ . Библиотека lodash создаёт функцию _ , а потом добавляет в неё _.clone , _.keyBy и другие свойства (чтобы узнать о ней побольше см. документацию). Они делают это, чтобы уменьшить засорение глобального пространства имён посредством того, что одна библиотека предоставляет только одну глобальную переменную, уменьшая вероятность конфликта имён.
Таким образом, функция может не только делать что-то сама по себе, но также и предоставлять полезную функциональность через свои свойства.
Задачи
Установка и уменьшение значения счётчика
важность: 5
Измените код makeCounter() так, чтобы счётчик мог уменьшать и устанавливать значение:
- counter() должен возвращать следующее значение (как и раньше).
- counter.set(value) должен устанавливать счётчику значение value .
- counter.decrease() должен уменьшать значение счётчика на 1.
Посмотрите код из песочницы с полным примером использования.
P.S. Для того, чтобы сохранить текущее значение счётчика, можно воспользоваться как замыканием, так и свойством функции. Или сделать два варианта решения: и так, и так.
В решении использована локальная переменная count , а методы сложения записаны прямо в counter . Они разделяют одно и то же лексическое окружение и также имеют доступ к текущей переменной count .
function makeCounter() < let count = 0; function counter() < return count++; >counter.set = value => count = value; counter.decrease = () => count--; return counter; >
Функции
В общем случае, функция — это «подпрограмма», которую можно вызывать из внешнего (или внутреннего, в случае рекурсии) по отношению к функции кода. Как и сама программа, функция состоит из последовательности инструкций, называемой телом функции. Значения могут быть переданы в функцию, а функция вернёт значение.
В JavaScript функции являются объектами первого класса, то есть: они являются объектами и с ними можно взаимодействовать и передавать их точно так же как любой другой объект. Если быть точным, функции — это объекты Function .
Больше подробностей и примеров можно найти в руководстве по функциям в JavaScript.
Описание
Каждая функция в JavaScript — это объект Function. О свойствах и методах объектов Function можно прочитать в статье Function .
Функции — это не процедуры. Функция всегда возвращает значение, а процедура может возвращать, а может не возвращать.
Чтобы вернуть значение, отличное от значения по умолчанию, в функции должна быть инструкция return , которая указывает, что именно нужно вернуть. Функция без него вернёт значение по умолчанию. В случае конструктора, вызванного с ключевым словом new , значение по умолчанию — это значение его параметра this . Для остальных функций значением по умолчанию будет undefined .
Параметры вызова функции называются аргументами функции. Аргументы передаются в функцию по значению. Если функция изменяет значение аргумента, это изменение не отражается на глобальном состоянии или вызывающей функции. Однако ссылки на объекты — это тоже значения, и они отличаются тем, что если функция изменяет свойства объекта по ссылке, это изменение видно снаружи функции, как показано в примере ниже.
/* Объявляем функцию 'myFunc' */ function myFunc(theObject) theObject.brand = "Toyota"; > /* * Объявляем переменную 'mycar'; * создаём и инициализируем новый Object; * приравниваем 'mycar' к ссылке на него */ var mycar = brand: "Honda", model: "Accord", year: 1998, >; /* Выведет 'Honda' */ console.log(mycar.brand); /* Передаём ссылку на объект в функцию */ myFunc(mycar); /* * Выведет 'Toyota', так как значение свойства 'brand' * было изменено внутри функции. */ console.log(mycar.brand);
Ключевое слово this не ссылается на функцию, которая выполняется в данный момент, поэтому вы должны обращаться к объектами Function по имени, даже внутри тела самой функции.
Определение функций
Есть несколько способов определить функцию:
Объявление функции (инструкция function )
Специальный синтаксис для объявления функций (более подробно: function statement):
function name([param[, param[, . param]]])
Имя аргумента, передаваемого в функцию. У функции может быть не более 255 аргументов.
Инструкции, из которых состоит тело функции.
Функция-выражение (оператор function )
Функция-выражение похожа на определение функции и имеет такой же синтаксис (более подробно: function operator):
function [name]([param] [, param] [. param])
Имя функции. Может быть не указано, в таком случае функция становится анонимной.
Имя аргумента, передаваемого в функцию. У функции может быть не более 255 аргументов.
Инструкции, из которых состоит тело функции.
Стрелочная функция-выражение (=>)
Примечание: стрелочные функции являются экспериментальной технологией*,* частью спецификации ECMAScript 6 и пока что не поддерживаются всеми браузерами.
Стрелочные функции отличаются более кратким синтаксисом и тем, что они лексически связывают значение своего this (подробнее об этом в статье Стрелочные функции):
([param] [, param]) => < statements >param => expression
Имя параметра. Если параметров нет, вместо них нужно поставить (). Если параметров больше одного, их также нужно заключить в ().
Если инструкций несколько, их нужно заключить в <>. Для одного выражения фигурных скобок не требуется, а результат этого выражения будет возвращён функцией (то есть` функция x => 3 + 8 вернёт 11).«`
Конструктор Function
Примечание: Использовать конструктор Function не рекомендуется, так как он принимает тело функции в виде строки, а это может помешать оптимизациям, которые выполняют движки JavaScript, а также привести к другим проблемам.
Объекты Function можно создавать с помощью оператора new (как и любые другие объекты):
new Function (arg1, arg2, . argN, functionBody)
Ноль или больше имён параметров функции. Имя должно быть строкой, содержащей валидный идентификатор JavaScript. Если параметров несколько, они должны быть разделены запятыми. Например: » x «, » theValue «, или » a,b «.
Инструкции, из которых состоит тело функции.
Конструктор Function можно вызывать и без оператора new, эффект будет тем же.
Параметры функции
Примечание: Остаточные параметры и параметры по умолчанию — это экспериментальная технология, часть спецификации ECMAScript 6, и они пока ещё не получили широкой поддержки среди браузеров.
Параметры по умолчанию
Параметры функции по умолчанию позволяют инициализировать формальные параметры со значениями по умолчанию, если им не было передано значение, или было передано undefined . Подробнее о них можно узнать в статье Параметры по умолчанию.
Остаточные параметры
Синтаксис оставшихся параметров позволяет передать бесконечное число аргументов как массив. Подробности можно найти в статье Остаточные параметры.
Объект arguments
Внутри функции получить доступ к её аргументам можно через объект arguments.
- arguments (en-US): Объект, похожий на массив и содержащий все аргументы, переданные в текущую функцию.
- arguments.callee (en-US) Устарело : Функция, исполняемая в текущий момент.
- arguments.caller : Функция, которая вызвала текущую функцию.
- arguments.length (en-US): Число аргументов, переданных в функцию.
Определение методов
Геттеры и сеттеры
Можно определять геттеры (методы для чтения) и сеттеры (методы для изменения) для любого встроенного или пользовательского объекта, который поддерживает добавление новых свойств. Для этого используется синтаксис литерала объекта.
Связывает свойство объекта с функцией, которая будет вызвана при обращении к свойству.
Связывает свойство объекта с функцией, которая будет вызвана при попытке изменения свойства.
Синтаксис определения методов
Примечание: Определение методов — это экспериментальная технология, часть спецификации ECMAScript 6, и она пока ещё не получила широкой поддержки среди браузеров.
Начиная с ECMAScript 6, можно определять собственные методы, используют более краткий синтаксис, похожий на геттеры и сеттеры. Более подробно — в статье Определение методов.
var obj = foo() >, bar() >, >;
Сравнение конструкторов Function с объявлением функций и функциями-выражениями
Посмотрите на следующие примеры:
Функция, определённая через конструктор Function и приравненная к переменной multiply:
var multiply = new Function("x", "y", "return x * y");
Объявление функции multiply:
function multiply(x, y) return x * y; >
Анонимная функция-выражение, приравненная к переменной multiply:
var multiply = function (x, y) return x * y; >;
Функция-выражение с именем func_name , приравненное к переменной multiply:
var multiply = function func_name(x, y) return x * y; >;
Отличия
Во всех случаях результат примерно одинаков, но есть несколько нюансов:
Имя функции и переменная, к которой функция приравнена — это не одно и то же. Имя функции нельзя менять, а вот переменной, к которой приравнена функция, можно дать другое значение. В случае функции-выражения с именем, это имя может быть использовано только внутри самой функции. При попытке использовать его снаружи возникнет ошибка (а если ранее была объявлена переменная с таким именем, будет возвращено undefined ). Например:
var y = function x() >; alert(x); // выкинет ошибку
Также имя функции-выражения проявляется, если сериализовать функцию через метод Function.toString.
А вот переменная, к которой функция приравнена, ограничена только собственной областью видимости, которая включает ту область, где функция была объявлена.
Как показано в четвёртом примере, имя функции может отличаться от имени переменной, к которой функция приравнена, эти имена никак не связаны. Объявление функции (function declaration) также создаёт и переменную с именем, аналогичным имени функции. Таким образом:
- Если функция определена с помощью функции-выражения (function expression), её имя доступно только внутри самой функции.
- Если функция объявлена (function declaration), её имя доступно в той области видимости, где функция была определена.
У функции, определённой с помощью ‘ new Function’ , нет имени. Однако, в JavaScript движке SpiderMonkey, сериализованное представление функции отображается так, как будто оно имеет имя «anonymous». Например, , alert(new Function()) выдаст:
function anonymous() >
Так как на самом деле у функции нет имени, переменную anonymous нельзя использовать внутри функции. Например, следующий пример выкинет ошибку:
var foo = new Function("alert(anonymous);"); foo();
В отличии от функций, определённых через функцию-выражение или конструктор Function , функция, определённая через объявление, может быть использована перед тем, как была определена. Например:
foo(); // выведет FOO! function foo() alert("FOO!"); >
Функция, определённая через функцию-выражение, наследует текущую область видимости, то есть создаёт замыкание. А вот функция, созданная с помощью конструктора Function , не наследует ничего, кроме глобальной области видимости (её наследуют вообще все функции).
Функции, определённые через функцию-выражение и объявление функции парсятся только один раз, в отличии от функций, созданных с помощью конструктора. То есть строка, которая передаётся в конструктор Function , парсится при каждом вызове конструктора. И хотя функция-выражение каждый раз создаёт замыкание, тело функции при этом не парсится, и получается, что функции-выражение всё равно быстрее, чем » new Function(. ) «. Поэтому конструктора Function в большинстве случаев стоит избегать, если это возможно.
Стоит отметить, что функции-выражения и объявления функций внутри функции, созданной при парсинге конструктора Function , парсятся только один раз. Например:
var foo = new Function( "var bar = 'FOO!';\nreturn(function() );", )(); foo(); // "function() " Эта часть строки, составляющей тело функции, не парсится во второй раз.
Объявление функции можно очень легко (и часто случайно) превратить в функцию-выражение. Объявление функции перестаёт быть таковым, если оно:
- становится частью выражения
- не является «исходным элементом» функции или файла. Исходный элемент — это не вложенный элемент внутри функции или скрипта:
var x = 0; // исходный элемент if (x == 0) // исходный элемент x = 10; // не исходный элемент function boo() > // не исходный элемент > function foo() // исходный элемент var y = 20; // исходный элемент function bar() > // исходный элемент while (y == 10) // исходный элемент function blah() > // не исходный элемент y++; // не исходный элемент > >
Примеры
// объявление функции function foo() > // функция-выражение (function bar() >); // функция-выражение x = function hello() >; if (x) // функция-выражение function world() > > // объявление функции function a() // объявление функции function b() > if (0) // функция-выражение function c() > > >
Определение функции в зависимости от условия
Функции могут быть определены в зависимости от условий с помощью инструкции function (разрешённое расширение стандарта ECMA-262 Edition 3) или конструктора Function . Обратите внимание, что подобные инструкции запрещены в ES5 strict. Кроме того, эта возможность по-разному ведёт себя в разных браузерах, поэтому не стоит на неё рассчитывать.
В коде ниже функция zero никогда не будет определена и не может быть вызвана, потому что ‘ if (0) ‘ всегда расценивается как false :
if (0) function zero() document.writeln("This is zero."); > >
Если изменить условие на ‘ if (1) ‘, функция zero будет определена.
Заметьте, что хотя это выглядит как объявление функции, на самом деле, это функция-выражение (или инструкция), так как она вложена внутрь другой инструкции. Изучите разницу между объявлением функции и функцией-выражением.
Некоторые JavaScript-движки (но не SpiderMonkey), неверно считают любую функцию-выражение с именем за объявление функции. Это приводит к тому, что функция zero будет определена, даже если условие всегда false . Более безопасный способ определить функцию по условию — это сделать её анонимной и приравнять к переменной:
if (0) var zero = function () document.writeln("This is zero."); >; >
Примеры
Пример: возврат отформатированного числа
Эта функция возвращает строку, содержащую число с заданным количеством нулей перед ним:
function padZeros(num, totalLen) var numStr = num.toString(); // Инициализировать возвращаемое значение в виде строки var numZeros = totalLen - numStr.length; // Посчитать число нулей в начале for (var i = 1; i numZeros; i++) numStr = "0" + numStr; > return numStr; >
var result; result = padZeros(42, 4); // возвращает "0042" result = padZeros(42, 2); // возвращает "42" result = padZeros(5, 4); // возвращает "0005"
Пример: существует ли функция
Можно определить, существует ли функция с помощью оператора typeof . В следующем примере проверяется, есть ли у объекта window функция noFunc . Если есть, то она вызывается; если нет, выполняется какое-то другое действие.
if ("function" == typeof window.noFunc) // вызывать noFunc() > else // сделать что-то другое >
Заметьте, что в проверке условия используется ссылка на noFunc — после имени функции нет скобок, поэтому сама функция не вызывается.
Спецификации
| Specification |
|---|
| ECMAScript Language Specification # sec-function-definitions |
Поддержка браузерами
BCD tables only load in the browser
Смотрите также
- Function
- Инструкция function
- Оператор function
Found a content problem with this page?
- Edit the page on GitHub.
- Report the content issue.
- View the source on GitHub.
This page was last modified on 4 авг. 2023 г. by MDN contributors.
Your blueprint for a better internet.
MDN
Support
- Product help
- Report an issue
Our communities
Developers
- Web Technologies
- Learn Web Development
- MDN Plus
- Hacks Blog
- Website Privacy Notice
- Cookies
- Legal
- Community Participation Guidelines
Visit Mozilla Corporation’s not-for-profit parent, the Mozilla Foundation.
Portions of this content are ©1998– 2023 by individual mozilla.org contributors. Content available under a Creative Commons license.
