Как передать имя объекта в качестве параметра через переменную, определенную как функцию, в другую функцию?

В моем расширенном коде я получаю TypeError, и я думаю, что это связано с тем, что я не смог успешно передать объект в качестве параметра из одной функции, затем через переменную, определенную как функцию, а затем в конечную функцию.

Точнее, я вызываю переменную executeOnce (которая определена как функция) и передаю ей параметр options. Затем эта самовыполняющаяся функция должна передать этот параметр options в funB() (то есть funB(options)), но я не думаю, что переданный аргумент доходит до funB(). Отсюда ошибка.

Что мне не хватает?

В приведенном ниже коде это работает, если я заменяю funB(options); на строку (т. е. funB("options");), но я не могу этого сделать, потому что в моем расширенном коде я передаю различные аргументы.

const obj = {
    options: {
        spam: 4
    },
};

function funB(options) {
    obj[options].spam = 6; // the console log below should print "6" but doesn't
}

var executeOnce = (function (options) {
    var executed = false;
    return function () {
        if (!executed) {
            executed = true;
            funB(options); // the function works if i change this to 'funB('options');'
        }
    };
})();

funA('options');
function funA(options) {
    executeOnce(options);
}

console.info('= ' + obj.options.spam)

Почему ты звонишь funA('optionsA');. Я думаю это funA('options');

Ryan Nghiem 09.04.2019 05:40

Спасибо, @RyanNghiem, я обновил свой пост, чтобы исправить эту ошибку, но это не решает мою большую проблему.

forestkelley 09.04.2019 06:49

Я не за компьютером, но я почти уверен, что, поскольку executeOnce возвращает функцию, вам действительно нужно вызвать executeOnce(options)() в funA.

Nate 09.04.2019 07:20
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
3
704
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

    const obj = {
        options: {
            spam: 4
        },
    };

    function funB(options) {
        if (obj[options]==undefined)
          obj[options] = {};
        obj[options].spam = 6;
    }

    var executeOnce = (function (options) {
        var executed = false;
        return function (options) {
            if (!executed) {
                executed = true;
                funB(options); // the function works if i change this to 'funB('options');'
            }
        };
    })();
    funA('optionsA');
    function funA(options) {
        executeOnce(options);
    }
    console.info(obj)

Спасибо, @MohammedMessaoudi, но ваше решение не решает проблему, потому что использование записи через точку не позволяет мне передать имя объекта в качестве аргумента.

forestkelley 09.04.2019 06:47

ты сейчас? если не ок! Пожалуйста, дайте мне знать!

Mohammed Messaoudi 09.04.2019 06:54

Неа. Это все еще не работает. Он просто возвращает объект. Но когда я console.info(obj.options.spam:); возвращает 4, а не обновленную 6, как следует.

forestkelley 09.04.2019 07:02

вы знаете, что var executeOnce = (function (опции) {... не определено? потому что вы не передали аргумент функции executeOnce при первом запуске!

Mohammed Messaoudi 09.04.2019 07:06

Разве executeOnce(options); не переходит options в var executeOnce? Я подозреваю, что проблема, как вы предполагаете, заключается в этом процессе передачи аргумента от function funA(options) к var executeOnce, но я не уверен, как еще это написать?

forestkelley 09.04.2019 07:12

так почему вы установили "вариант А"? почему вы не установили funA('options'); ? так что вы можете обновить свойство спама до 6

Mohammed Messaoudi 09.04.2019 07:22

Я должен был установить options, а не optionsA. Это была ошибка, которую @Nate поймал выше. Я исправил это в своем посте, но это не было центральной проблемой.

forestkelley 09.04.2019 19:15
Ответ принят как подходящий

Вы ошибаетесь в executeOnce, вы используете синтаксис immediate function для создания значения для переменной executeOnce (звучит хорошо), но executeOnce — это функция без any параметров, вы можете увидеть оператор return.

var executeOnce = (function (options) { // `options` - does not make sense
    var executed = false;
    return function () {
        if (!executed) {
            executed = true;
            funB(options);
        }
    };
})();

Попробуйте мой способ, верните функцию, у которой есть параметр options.

 var executeOnce = (function () {
    var executed = false;
    return function (options) {
        if (!executed) {
            executed = true;
            funB(options);
        }
    };
})();

Великолепно! Это работает. Мне не приходило в голову передать параметр options в функцию возврата.

forestkelley 09.04.2019 07:25

Я думаю, вы можете создать на одну функцию больше, чем вам нужно, но это ничего не сломает. Проблема, по-видимому, заключается в том, что возвращаемая функция (замыкание) не знает о options, что можно решить, передав options в качестве аргумента при вызове возвращаемой функции.

Я дал возвращаемой функции имя newFunc, а также добавил операторы печати по всему скрипту, чтобы прояснить, что происходит на каждом этапе (что значительно упростило отладку).

// Main
const obj = { options: { spam: 4 } };
funA(obj.options);
console.info("finally...");
console.info('obj.options.spam = ' + obj.options.spam);

// Functions
function funB(options){
  console.info("funB got..."); console.info(options);
  options.spam = 6;
  console.info("funB set options to..."); console.info(options);
}

function executeOnce(options){
  // context for closure (IIFE)
  console.info("executeOnce got..."); console.info(options);
  var executed = false;
  var newFunc = function(options){
    console.info("newFunc got..."); console.info(options);
    if (!executed){
      executed = true;
      funB(options);
    }
  };
  return newFunc(options);
};

function funA(options){ 
  console.info("funA got..."); console.info(options);
  executeOnce(options);
}

Я вижу, что @hoangdv уже указал на проблему (и использовал только отладчик в своем уме). Хорошее шоу.

Cat 09.04.2019 08:27

Другие вопросы по теме