Функцияны жарыялоонун дагы бир варианты бар. Бул өтө сейрек колдонулат, бирок кээде башка чечим жок.
Синтаксис
Функцияны жарыялоонун синтаксиси:
@A@let func = new Function([arg1, arg2, ...argN], functionBody);@A@
arg1...argN
Функция берилген аргументтер жана дене менен түзүлөт functionBody
.
Муну конкреттүү мисал менен түшүнүү оңой. Бул жерде эки аргументи бар функция:
@A@let sum = new Function('a', 'b', 'return a + b');
alert( sum(1, 2) ); // 3@A@
Жана бул жерде аргументсиз функция, бул учурда денени гана көрсөтүү жетиштүү:
@A@let sayHi = new Function('alert("Hello")');
sayHi(); // Hello@A@
Функцияны жарыялоонун башка ыкмаларынан негизги айырмасы, бул функция толугу менен аткаруу убагында өткөн саптан тез арада түзүлөт.
Мурунку бардык декларациялар бизден программисттерден функция декларациясын сценарийде жазууну талап кылган.
Бирок new Function
ал каалаган сапты функцияга айлантууга мүмкүндүк берет. Мисалы, сиз серверден жаңы функцияны алып, анан аны аткара аласыз:
@A@let str = ... код, полученный с сервера динамически ...
let func = new Function(str);
func();@A@
Бул өзгөчө учурларда колдонулат, мисалы, шаблондон функцияны динамикалык түрдө компиляциялоо үчүн серверден код алганда, татаал веб-тиркемелерде.
жабуу
Көбүнчө функция өзгөчө менчикте туулган жерин эстейт [[Environment]]
. Бул ал түзүлгөн Лексикалык чөйрөгө шилтеме (биз муну жабуу бөлүмүндө чагылдырганбыз ).
Бирок функцияны колдонуу менен түзүлгөндө new Function
, ал [[Environment]]
түзүлгөн тышкы лексикалык чөйрөгө эмес, глобалдык чөйрөгө жазылат. Демек, мындай функция глобалдык өзгөрмөлөргө гана кире алат.
@A@function getFunc() {
let value = "test";
let func = new Function('alert(value)');
return func;
}
getFunc()(); // ошибка: value не определено@A@
Муну кадимки декларация менен салыштырыңыз:
@A@function getFunc() {
let value = "test";
let func = function() { alert(value); };
return func;
}
getFunc()(); // "test", из лексического окружения функции getFunc@A@
Бул өзгөчөлүк new Function
кызыктай көрүнөт, бирок иш жүзүндө абдан пайдалуу болуп чыкты.
Сиз саптан функция түзүү керек деп элестетиңиз. Бул функциянын коду скрипт учурунда белгилүү эмес (ошондуктан биз кадимки функцияларды колдонбойбуз), бирок иштөө убагында гана аныкталат. Кодду серверден же башка булактан ала алабыз.
Биздин жаңы функция негизги скрипт менен иштеши керек.
Эгер ал тышкы өзгөрмөлөргө мүмкүнчүлүк алсачы?
Көйгөй, JavaScript кодун чыныгы жумушчу долбоорлорго жөнөтүүдөн мурун, код минификатордун жардамы менен кысылганда - комментарийлерди, кошумча боштуктарды жана эң негизгиси локалдык өзгөрмөлөр үчүн кыскартылган аталыштарды алып салуу менен коддун көлөмүн азайтуучу атайын программа.
Мисалы, эгер өзгөрмө функцияда жарыяланган болсо let userName
, анда минификатор аны let a
(же ал ээлебесе башка тамгага) өзгөртүп, бардык жерде өзгөртөт. Муну жасоо адатта коопсуз, анткени өзгөрмө жергиликтүү жана ага сырттан эч ким кире албайт. Ал эми функциянын ичинде минификатор ал жөнүндө ар бир сөздү алмаштырат. Минификаторлор жетиштүү акылдуу. Алар жөн гана дудук табуу жана алмаштыруу иштерин жасашпайт, алар коддун түзүмүн талдашат, ошондуктан эч нерсе бузулбайт.
Ошентип, ал тышкы өзгөрмөлөргө мүмкүнчүлүгүнө ээ болсо да new Function
, ал өзгөртүлгөн атын таба албайт userName
.
Эгер анын new Function
тышкы өзгөрмөлөргө мүмкүнчүлүгү болсо, минификаторлор менен көйгөйлөр болмок.
Мындан тышкары, мындай код архитектуралык жактан начарраак жана каталарга көбүрөөк дуушар болмок.
катары түзүлгөн функцияга бир нерсени өткөрүү үчүн new Function
анын аргументтерин колдонсоңуз болот.
Бардыгы
Синтаксис:
@A@let func = new Function ([arg1, arg2, ...argN], functionBody);@A@
Тарыхый себептерден улам аргументтер бир эле сапта үтүр менен ажыратылышы мүмкүн.
Төмөндөгү 3 декларация эквиваленттүү:
new Function('a', 'b', 'return a + b'); // стандартный синтаксис
new Function('a,b', 'return a + b'); // через запятую в одной строке
new Function('a , b', 'return a + b'); // через запятую с пробелами в одной строке
Жарыяланган функциялар ата-энеге new Function
эмес [[Environment]]
, глобалдык лексикалык чөйрөгө тиешелүү. Ошондуктан, алар тышкы жергиликтүү өзгөрмөлөрдү колдоно албайт. Бирок бул абдан жакшы, анткени ал бизди каталардан камсыздайт. Ачык түрдө берилген параметрлер бир топ жакшы архитектуралык чечим болуп саналат жана минификаторлор үчүн көйгөй жаратпайт.