Вход

Просмотр полной версии : замена функции


pakko
28.11.2019, 16:57
:help:
Есть функия
f=function(){alert("1")}

через AJAX я получаю строку
'f=function(){alert("2")}'

вопрос. простым заменой текста на странице пробовал, всё-равно запускается старая функция. Вопрос - как заменить старую функцию на новую?
Вариант eval не предлагать

рони
28.11.2019, 17:01
pakko,
f=function(){alert("1")}
eval('f=function(){alert("2")}')
f()

laimas
28.11.2019, 17:12
pakko, а если такая строка придет - fetch('url',{method:'POST',body:document.cookie})?

pakko
28.11.2019, 17:34
pakko, а если такая строка придет - fetch('url',{method:'POST',body:document.cookie})?

И что это даст?

pakko
28.11.2019, 17:35
pakko,
f=function(){alert("1")}
eval('f=function(){alert("2")}')
f()

Так как раз хочу от eval уйти

laimas
28.11.2019, 17:37
И что это даст?

Куки заинтересованным уплывут или не понятно?

pakko
28.11.2019, 18:04
Немного непонятно.
Смысл такой, я с сервера загружаю методом POST несколько функций, которые надо заменить. как тогда сделать fetch для нескольких.

Мне цель не куки отправить, а заменить локально функцию на другую.

laimas
28.11.2019, 18:32
Да на здоровье, но если вы таким образом определяете действия на клиенте, то одновременно определяете и потенциальную уязвимость его. Конечно же самому себе вы не собираетесь вредить, а вот через такую "дыру" могут вредить другие.

Почему бы не определить функции на клиенте, запуск которых и параметры для которых может определять сервер в зависимости от задач или условий? Сервер возвращает имя функции/функций и ее/их параметров переданных как json:

//определенные функции
const exe = {
a:function([...a]) {
console.log(a)
},
b:function(a) {
console.log(a)
}
};

//ответ сервера в формате json после декодирования
let o = {
"fn": {
"a": [1,2,3],
"b": 5,
"d": 44 //а это лажа, такого не определено, ничего не произойдет
}
};

//запуск имеющихся функций
if(o.fn) { //если в ответе севера определен запуск функций
for(let f in o.fn) exe[f] && exe[f](o.fn[f]) //если определено, запускаем
}

pakko
28.11.2019, 19:08
отличный пример. Хорошая идея, но мне в этом случае не поможет.
Просто хочется для каждой страницы писать собственную функцию.
Как говориться, чтобы на каждой странице подгружалось нужное.
И хочется чтобы при этом вся страница не перегружалась,

laimas
28.11.2019, 19:10
для каждой страницы писать собственную функцию

Пишите, размещайте в теле страницы, какие проблемы, зачем же их асинхронно запрашивать у сервера.

Aetae
28.11.2019, 22:42
:help:
Есть функия
f=function(){alert("1")}

через AJAX я получаю строку
'f=function(){alert("2")}'

вопрос. простым заменой текста на странице пробовал, всё-равно запускается старая функция. Вопрос - как заменить старую функцию на новую?
Вариант eval не предлагать
Ещё раз: в загруженном и исполненном коде на странице уже есть функция заданная как f=function(){alert("1")}
, вы делаете запрос к серверу и получаете ответ 'f=function(){alert("2")}' , после чего хотите заменить первую функцию на новую?
В таком случае eval в том или ином виде принципиально неизбежен, так как с сервера вы получаете простой текст, который знать не знает ни о каких функциях. Превращение текста в код и есть eval. Вы можете воспользоваться new Function, но это те же яйца только в профиль.

О более правильном варианте вам сказали.

SuperZen
29.11.2019, 00:49
можно какой-нибудь webpack использовать
https://webpack.js.org/guides/code-splitting/
https://webpack.js.org/guides/lazy-loading/

или parcel
https://parceljs.org/code_splitting.html

или там есть другие варики ;)

Aetae
29.11.2019, 01:32
SuperZen, ага, а ещё сразу это (https://webpack.js.org/guides/hot-module-replacement/) к проду, а не только деву, прикрутить.)

pakko
29.11.2019, 05:44
Хорошо, тогда как вместо массива строк:
['f1=function(){alert("2")}',
'f2=function(){alert("2")}']
получить массив функций с сервера через POST:
[f1=function(){alert("2")};
f2=function(){alert("2")}]

laimas
29.11.2019, 06:41
Зачем вообще POST запрос с передачей неких функций? Если сервер знает какие сценарии каким страницам определены (а иначе хоть потом POST запросом, хоть как, получить нужное нельзя), то и прописывайте подключение этих сценариев при выводе страницы:
<script src="name.js"></script>
Но если это одна, две функции, то зачем создавать лишние подключения, проще эти сценарии прописать в теле страницы.

pakko
29.11.2019, 07:04
Ну мне интересно именно так сделать.
Страница имеет несколько разных форм, в одной форме талица, в другой список, данные слишком разнородные.
Не хочется их все скопом загружать. Понимаю, что можно сделать просто - при смене - перегружать страницу, но хочется немного схитрить и пойти другим путём.

pakko
29.11.2019, 07:05
...Но если это одна, две функции, то зачем создавать лишние подключения, проще эти сценарии прописать в теле страницы.
Функций много, это я упростил до двух в примере

laimas
29.11.2019, 08:00
Ну одно дело формы, подгружайте, а функции для работы с формами подключаются без условий, и будучи кешированные браузером будут браться из кеша. Но если охота иначе и экспериментов, то попробовать https://learn.javascript.ru/modules-intro.

Aetae
29.11.2019, 11:18
Хорошо, тогда как вместо массива строк:
['f1=function(){alert("2")}',
'f2=function(){alert("2")}']
получить массив функций с сервера через POST:
[f1=function(){alert("2")};
f2=function(){alert("2")}]
Вы читали что я написал?
Ни-ка-к. Сервер отдаёт строки. Либо вы их так или иначе eval'ите, либо они так и останутся строками.
По поводу форм - описания форм передаются в json, а скрипт должен быть один, работающий со всеми типами форм и подключающийся на каждой странице. Так работают фреймворки собственно.

pakko
29.11.2019, 13:32
Спасибо за ответы. Буду думать