Форум программистов, компьютерный форум, киберфорум
JavaScript для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.61/18: Рейтинг темы: голосов - 18, средняя оценка - 4.61
0 / 0 / 0
Регистрация: 05.04.2019
Сообщений: 54

Не работает анонимная функция

23.07.2019, 23:39. Показов 3918. Ответов 18
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый вечер, господа!
Делаю простенькие задания на JS и на одном из них встал в ступор при использовании анонимной функции
HTML5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>Ассоциативные массивы, упражнение 1</title>
    <script src="script.js" defer></script>
  </head>
  <body>
    <b>Описание человека:</b>
    <p>Имя: <input type="text" id="name"></p>
    <p>Фамилия: <input type="text" id="surname"></p>
    <p>Пол: <input type="text" id ="sex"></p>
    <p>Индивидуальный номер: <input type="text" id="individual number"></p>
    <p>Возраст: <input type="text" id="age"></p>
    <button onclick="f1()">Отправить в массив</button>
    <hr>
    <p id="out"></p>
  </body>
</html>
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
// создание ассоциативного массива с готовыми ключами
var human = {
  "name" : "значение не введено",
  "surname" : "значение не введено",
  "sex" : "значение не введено",
  "individual number" : "значение не введено",
  "age" : "значение не введено",
  "year" : "значение не введено"
};
 
// заполнение массива
function f1() {
  var n1, n2, n3, n4, n5;
  n1 = document.getElementById("name").value;
  n2 = document.getElementById("surname").value;
  n3 = document.getElementById("sex").value;
  n4 = document.getElementById("individual number").value;
  n5 = document.getElementById("age").value;
 
  human = {
    "name" : n1,
    "surname" : n2,
    "sex" : n3,
    "individual number" : n4,
    "age" : n5,
    "year": function () {
      return 2019 - this.age
    }
 
  }
  // human ["name"] = n1;
  // human ["surname"] = n2;
  // human ["sex"] = n3;
  // human ["individual number"] = n4;
  // human ["age"] = n5;
  // human ["year"] = 2019 - n5;
 
 
  // получил в переменную p параграф с id "out"
  var p = document.getElementById("out");
  // Вывод массива.
  for (var key in human) {
    p.innerHTML += key + "___" + human[key]+"<br>";
  }
}
(https://codepen.io/fesenkobv/pen/jgqNdy).
Вместо выполнения этой самой функции происходит вывод ее в параграф в виде строки.
Прошу потыкать носом.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
23.07.2019, 23:39
Ответы с готовыми решениями:

Анонимная функция
Небольшой код с анонимной функцией. Скажите каким образом при выводе сообщения через alert к Hello добавляется Mike? var myAlert =...

Анонимная самовызывающаяся функция
Почему анонимную функцию нельзя вызвать без круглых скобок? Нет ошибок: (function(){ //do something })(); Ошибка: ...

Анонимная функция нахождения произвидения 2 чисел
Задание: Анонимная функция нахождения произвидения 2 чисел. Пытался сделать самостоятельно нечего адекватного не вышло...

18
Эксперт JS
2037 / 1096 / 409
Регистрация: 29.04.2016
Сообщений: 2,625
24.07.2019, 03:36
Лучший ответ Сообщение было отмечено Борис Ф как решение

Решение

Борис Ф,

https://codepen.io/Mr_Sergo/pe... itors=1010
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
var human = {
    "name" : "значение не введено",
    "surname" : "значение не введено",
    "sex" : "значение не введено",
    "individual number" : "значение не введено",
    "age" : "значение не введено",
    "year" : "значение не введено"
};
 
function f1() {
    var n1, n2, n3, n4, n5;
    n1 = document.getElementById("name").value;
    n2 = document.getElementById("surname").value;
    n3 = document.getElementById("sex").value;
    n4 = document.getElementById("individual number").value;
    n5 = document.getElementById("age").value;
 
    human = {
        "name" : n1,
        "surname" : n2,
        "sex" : n3,
        "individual number" : n4,
        "age" : n5,
        "year" : function(){ 
            return 2019 - this.age;
        }
    };
 
    var p = document.getElementById("out");
 
    for (var key in human) {
        if(typeof human[key] == 'function') p.innerHTML += key + "___" + human[key]()+"<br>";
        else p.innerHTML += key + "___" + human[key]+"<br>";
    }
}
32 и 33 строки

Добавлено через 2 минуты
function обычно вызывается со скобками на конце, а вы в цикле вызываете все без скобок, поэтому сначала нужно проверить тип свойства а потом уже выполнять то или иное действие (со скобками или без)

Добавлено через 1 час 20 минут
Что бы вам было понятней -> https://codepen.io/Mr_Sergo/pe... itors=0012
JavaScript
1
2
3
4
5
6
7
8
var human = {
    "year" : function(){ 
        return 2019 - 10;
    }
};
 
console.log(human.year);    // так выведется содержимое функции
console.log(human.year());  // так результат ее выполнения
0
54 / 11 / 0
Регистрация: 28.11.2017
Сообщений: 50
24.07.2019, 05:00
Чтобы присвоить результат работы функции нужно чтобы функция что-то отдала. А у вас она написана, но не вызывается, ничего не отдаёт, а сама становится значением свойства. Тогда можно сделать её самовызывающейся, то есть обтянуть скобками и подставить скобки, как бы вызывая то, что в скобках.
Но тут возникает проблема - функция использует свойство объекта, в тот момент когда самого объекта ещё нет. Он находится на стадии строительства.
Тогда используем то что уже есть в этот момент - n5. И вуаля! Всё работает.
JavaScript
1
2
3
"year": (function () {
      return 2019 - n5
    })()
Но такой способ - это какой-то хитроманский подбор.
Мне больше нравится, то что предложил Mr_Sergo. Это круто и универсально.
0
Эксперт JS
6496 / 3907 / 2006
Регистрация: 14.06.2018
Сообщений: 6,781
24.07.2019, 06:31
Лучший ответ Сообщение было отмечено amr-now как решение

Решение

Покажу мелкие исправления, которые вроде и мелкие, но нужны для понимания, куда я попал и кто все эти буквы:
PHP/HTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
  <meta charset="utf-8">
  <title>Ассоциативные массивы, упражнение 1</title>
  <script>
    let human; // Глобальная переменная 
    document.addEventListener("DOMContentLoaded", onLoaded);
 
    function onLoaded() {
      // Обработчик на кнопку лучше навешивать в скрипте
      document.getElementById("btn").onclick = f1;
    }
 
    // заполнение массива
    function f1() {
      let
        n1 = document.getElementById("name").value,
        n2 = document.getElementById("surname").value,
        n3 = document.getElementById("sex").value,
        n4 = document.getElementById("individual number").value,
        n5 = document.getElementById("age").value;
 
      human = {
        "name": n1.length ? n1 : "значение не введено", 
        "surname": n2.length ? n2 : "значение не введено",
        "sex": n3.length ? n3 : "значение не введено",
        "individual number": n4.length ? n4 : "значение не введено",
        "age": n5.length ? n5 : "значение не введено",
        get ["year"]() { // Здесь по смыслу идеально подходит геттер
          return 2019 - this.age;
        }
      };
 
      // получил в переменную p параграф с id "out"
      let p = document.getElementById("out"),
        s = ""; // Строка, в которую набираем текст innerHTML
      // Вывод массива.
      for (let key in human) {
        s += key + "___" + human[key] + "<br>";
      }
      p.innerHTML = s; // В свойство HTML-элемента лучше присваивать не многократно.
    }
  </script>
</head>
 
<body>
  <b>Описание человека:</b>
  <p>Имя: <input type="text" id="name"></p>
  <p>Фамилия: <input type="text" id="surname"></p>
  <p>Пол: <input type="text" id="sex"></p>
  <p>Индивидуальный номер: <input type="text" id="individual number"></p>
  <p>Возраст: <input type="text" id="age"></p>
  <button id="btn">Отправить в массив</button>
  <hr>
  <p id="out"></p>
</body>
</html>
- Обработчик на кнопку лучше навешивать в скрипте.
- defer сильно устаревшая фича. Если есть большое желание, то изучите <script type="module"></script>
- Желательно использовать синтаксис ES2015. Синтаксис древних версий JavaScript - ну просто шлак.
Сейчас мало устройств, которым требуется синтаксис образца 2010 года.

В том числе и геттер в синтаксисе ES2015 очень даже удобен для данной конкретной задачи.
0
54 / 11 / 0
Регистрация: 28.11.2017
Сообщений: 50
24.07.2019, 06:42
Цитата Сообщение от amr-now Посмотреть сообщение
Обработчик на кнопку лучше навешивать в скрипте.
Хотел бы знать, почему? Мне всегда казалось, что лучше на кнопку. В скрипте всё как- то ненадёжно Кто-то чё-то может сказать по этому поводу?
А синтаксисом древних версий js пользуются, потому что боятся подорваться на не поддерживающим браузере. А так-то все бы и рады пользоваться новым. У новичков проблема как раз со старым.
Успехов!
0
Эксперт JS
2037 / 1096 / 409
Регистрация: 29.04.2016
Сообщений: 2,625
24.07.2019, 07:02
Цитата Сообщение от Jumpbystep Посмотреть сообщение
Хотел бы знать, почему?
Да по большому счету, наверное, кто как хочет так и делает. Суть в разделении кода: html- отвечает за разметку, js-отвечает за поведение, css- за стили. Тут неплохо расписано КЛАЦ

Немаловажно расширяемость проекта.
если сайт содержит сотни полей с данными, добавление соответствующего атрибута onchange к каждому (и модификация их позже в случае необходимости) может оказаться трудоёмкой процедурой
0
Эксперт JS
6496 / 3907 / 2006
Регистрация: 14.06.2018
Сообщений: 6,781
24.07.2019, 07:18
Цитата Сообщение от Jumpbystep Посмотреть сообщение
Кто-то чё-то может сказать по этому поводу?
https://en.wikipedia.org/wiki/... JavaScript
Separation of behavior from markup
Traditionally, JavaScript was often placed inline together with an HTML document's markup. For example, the following is a typical way to register a JavaScript event handler in HTML:
HTML5
1
<input type="text" name="date" onchange="validateDate()" />
The purpose of HTML markup is to describe a document's structure, not its programmatic behavior. Combining the two can negatively impact a site's maintainability, like combining content and presentation.[15] JavaScript behavior created and referenced in the HTML can be harder to use and maintain, for example when setting handlers for several events on a single element, when setting the same event handler on several elements, or when using event delegation.
The unobtrusive solution is to register the necessary event handlers programmatically, rather than inline. Rather than adding an onchange attribute explicitly as above, the relevant element(s) are simply identified, for example by class, id or some other means in the markup:
HTML5
1
<input type="text" name="date" id="date" />
A script that runs when the page is first loaded into the browser can then look for each relevant element and set it up accordingly:
JavaScript
1
2
3
window.addEventListener("DOMContentLoaded", function(event) {
    document.getElementById('date').addEventListener("change", validateDate);
})
;
Преимущества
- Поведение (Javascript) отделено от представления (HTML)
- Отсутствие смешивания языков
- Вы сможете использовать любой фреймворк javascript, например jQuery, который может обрабатывать большинство проблем с несколькими браузерами для вас.
- Вы можете добавить поведение к множеству HTML-элементов сразу без дублирования кода. И вообще гибкое управление поведением в отличие от статичной HTML-разметки.

Можно добавить, что код из атрибута HTML сначала преобразуется в анонимную функцию. То есть лишний шаг eval() и запуска ненужной функции-обертки.
-----
Там ещё есть причины, но итак уже понятно, куда бежать и где мои вещи.

Добавлено через 15 минут
Цитата Сообщение от Jumpbystep Посмотреть сообщение
А синтаксисом древних версий js пользуются
В ES5 тоже можно настроить геттер. Только он как суслик. Его никто не видел, но он есть.

Никто из присутствующих в этой теме не помнит, как в синтаксисе ES5 реализовать геттер. Зачем ? Если можно пользоваться синтаксисом ES2015. Или наворочать лапши.
0
0 / 0 / 0
Регистрация: 05.04.2019
Сообщений: 54
24.07.2019, 08:24  [ТС]
Спасибо, добрый люди!
Сижу разбираюсь.
0
54 / 11 / 0
Регистрация: 28.11.2017
Сообщений: 50
24.07.2019, 09:25
Цитата Сообщение от Mr_Sergo Посмотреть сообщение
Да по большому счету, наверное, кто как хочет так и делает. Суть в разделении кода: html- отвечает за разметку, js-отвечает за поведение, css- за стили.
Цитата Сообщение от amr-now Посмотреть сообщение
Преимущества
- Поведение (Javascript) отделено от представления (HTML)
- Отсутствие смешивания языков
...
Может стоит разделять проекты на большие и небольшие, когда порядок написания меняется на противоположный, потому что прежний, хороший в одном случае, становится более не оптимальным. Для небольших проектов смешивание структуры и поведения это благо, потому что найти и изменить что-то в разметке на порядок легче чем в джаваскрипте. В джаваскрипте мы создаём кучу лишних сущностей, чтобы навесить на них обработчики событий. Взять хотя бы этот пример. С каждым кликом создаётся и создаётся куча объектов для одних и тех же элементов. А если у пользователя припадки и он без конца нажимает кнопку. Никакой сборщик мусора не справится. Да и не у всех одинаковые обработчики, разные валидаторы, все перекрутить в одном цикле не получится. А кнопки, их же не настолько много на сайтах, чтобы ходить через улицу создавать для них где-то за забором переменные, только чтобы навесить обработчики.
О разделении данных и их представления нужно говорить только в контексте 4-х известных фреймворков. Вот там да, эта концепция просто окрыляет. Я оперирую данными а представление рождается и изменяется в соответствии с данными. А здесь надо делать не как говорят, что надо, а как удобно.
0
Эксперт JS
6496 / 3907 / 2006
Регистрация: 14.06.2018
Сообщений: 6,781
24.07.2019, 09:36
Цитата Сообщение от Jumpbystep Посмотреть сообщение
А если у пользователя припадки и он без конца нажимает кнопку.
В данном скрипте обработчик навешивается единственный раз при загрузке страницы. Абсолютно эквивалентно коду, внедренному в HTML-разметку.

По поводу поддержки IE8 тут у народа возникают разумные вопросы:
Ответ: Пишите программу на нормальном современном языке, а потом скрипт можно транспилировать в синтаксис древнего JavaScript.

Борис Ф даже дальновидно вынес скрипт в отдельный файл.
Потом можно будет подложить абсолютно любой файлик.
Хоть для нашего любимого Internet Explorer 6, которого горячо любят все авторы учебников и лекций.
0
54 / 11 / 0
Регистрация: 28.11.2017
Сообщений: 50
24.07.2019, 10:05
Цитата Сообщение от amr-now Посмотреть сообщение
В данном скрипте обработчик навешивается единственный раз при загрузке страницы. Абсолютно эквивалентно коду, внедренному в HTML-разметку.
Может я чего-то не понимаю (я реально чайник в js), но в коде чётко говорится: при клике СОЗДАТЬ! 5 переменных для инпутов и 1 для p навесить на них ссылки из Дома, забрать данные из элементов и передать их объекту. Свойства объекта отобразить в элементе p.
Следующий клик: СОЗДАТЬ! 5 переменных для инпутов и 1 для p...
Следующий клик: СОЗДАТЬ! 5 переменных для инпутов и 1 для p...
Это всегда новые переменные, в новых ячейках памяти, но с одинаковыми значениями - ссылками на одни и те же элементы.
На старые значения теряются ссылки и они лежат в памяти и ждут сборщика мусора.
0
Эксперт JS
6496 / 3907 / 2006
Регистрация: 14.06.2018
Сообщений: 6,781
24.07.2019, 10:18
Jumpbystep, в сторону разговор не заводите.
У нас не было цели сильно переделывать функцию f1().

В функции f1() надо было только решить вопрос с выводом года рождения. Вопрос решили. Вывели.
0
54 / 11 / 0
Регистрация: 28.11.2017
Сообщений: 50
24.07.2019, 10:22
Цитата Сообщение от amr-now Посмотреть сообщение
У нас не было цели сильно переделывать функцию f1().
В функции f1() надо было только решить вопрос с выводом года рождения. Вопрос решили. Вывели.
И то правда!
Борис Ф, простите что мы тут у вас нафлудили
0
Эксперт JS
6496 / 3907 / 2006
Регистрация: 14.06.2018
Сообщений: 6,781
24.07.2019, 10:42
Jumpbystep,
здесь можно порассуждать, а зачем мы постоянно создаем полностью нового человека?
Бывает.

Кстати, у Борис Ф в целом неплохой скрипт.
Гораздо хуже, когда программист думает, что он знает функциональное программирование, и начинает бесконечно оборачивать функцию в функцию.
0
0 / 0 / 0
Регистрация: 05.04.2019
Сообщений: 54
24.07.2019, 11:05  [ТС]
Еще раз спасибо, господа!
0
54 / 11 / 0
Регистрация: 28.11.2017
Сообщений: 50
24.07.2019, 11:12
Борис Ф, всё-таки мне кажется что лучше было бы вынести все инициализации наружу.
value у них убрать, так как пока там ничего нет.
А в объекте для n1-n5 value добавить через точку.
Оно так и так работает, но сдаётся мне, что так будет экономичней.
0
30.07.2019, 08:36

Не по теме:

Цитата Сообщение от Jumpbystep Посмотреть сообщение
сдаётся мне, что так будет экономичней
Интересное у вас тут обсуждение :D, приведу пару цитат
Преждевременная оптимизация — корень всех зол
https://ru.wikiquote.org/wiki/... 1%83%D1%82
Keep it simple, stupid
https://ru.wikipedia.org/wiki/... 0%B8%D0%BF)
You aren't gonna need it
https://ru.wikipedia.org/wiki/YAGNI

0
30.07.2019, 09:49

Не по теме:

А с каких пор метод объекта является анонимной функцией?

0
54 / 11 / 0
Регистрация: 28.11.2017
Сообщений: 50
30.07.2019, 15:10
Цитата Сообщение от j2FunOnly Посмотреть сообщение
Интересное у вас тут обсуждение , приведу пару цитат
Преждевременная оптимизация — корень всех зол
Какое отношение имеет преждевременная оптимизация к тому о чём я пытался сказать? Вариант с беспорядочной генерацией ненужных сущностей и переполнение памяти в принципе недопустимо, потому что даже небольшое приложение при таком подходе просто повесит компьютер. Ну давайте начнём делать тоже самое, но явно - постоянно генерировать большое количество переменных, а использовать будем только 0,1% из них. Это же просто глупо. Да конечно так можно, на простом примере всё будет работать, но это просто глупо и всё!
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
30.07.2019, 15:10
Помогаю со студенческими работами здесь

Что такое Анонимная Функция, где используется?
Здравствуйте. Расскажите, пожалуйста, что такое анонимная функция, для чего она нужна, и как она используется на практике. А так же,...

Анонимная функция и замыкание
Привет всем. Поясните пожалуйста верно ли я понял. Вот есть анонимная функция(онаже Лямбда-функци) с помощью которой делаем замыкание...

Анонимная функция в интегрировании
Здравствуйте, гуглил способы интегрирования в Matlab и наткнулся на функцию для числового интегрирования quadl. Для примера представлен...

Не срабатывает анонимная функция
Добрый день! Подскажите, пожалуйста, почему текст 'connect' в данном случае виден, а 'inner connect' нет? public function...

Анонимная функция, вернуть 2 параметра
Доброго времени! Подскажите, конструкцию как можно используя анонимную функцию @() или inline вернуть 2 и более параметров?


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
19
Ответ Создать тему
Новые блоги и статьи
Воспроизведение звукового файла с помощью SDL3_mixer при касании экрана Android
8Observer8 26.01.2026
Содержание блога SDL3_mixer - это библиотека я для воспроизведения аудио. В отличие от инструкции по добавлению текста код по проигрыванию звука уже содержится в шаблоне примера. Нужно только. . .
Установка Android SDK, NDK, JDK, CMake и т.д.
8Observer8 25.01.2026
Содержание блога Перейдите по ссылке: https:/ / developer. android. com/ studio и в самом низу страницы кликните по архиву "commandlinetools-win-xxxxxx_latest. zip" Извлеките архив и вы увидите. . .
Вывод текста со шрифтом TTF на Android с помощью библиотеки SDL3_ttf
8Observer8 25.01.2026
Содержание блога Если у вас не установлены Android SDK, NDK, JDK, и т. д. то сделайте это по следующей инструкции: Установка Android SDK, NDK, JDK, CMake и т. д. Сборка примера Скачайте. . .
Использование SDL3-callbacks вместо функции main() на Android, Desktop и WebAssembly
8Observer8 24.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
моя боль
iceja 24.01.2026
Выложила интерполяцию кубическими сплайнами www. iceja. net REST сервисы временно не работают, только через Web. Написала за 56 рабочих часов этот сайт с нуля. При помощи perplexity. ai PRO , при. . .
Модель сукцессии микоризы
anaschu 24.01.2026
Решили писать научную статью с неким РОманом
http://iceja.net/ математические сервисы
iceja 20.01.2026
Обновила свой сайт http:/ / iceja. net/ , приделала Fast Fourier Transform экстраполяцию сигналов. Однако предсказывает далеко не каждый сигнал (см ограничения http:/ / iceja. net/ fourier/ docs ). Также. . .
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru