В моем расширенном коде я получаю 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)
Спасибо, @RyanNghiem, я обновил свой пост, чтобы исправить эту ошибку, но это не решает мою большую проблему.
Я не за компьютером, но я почти уверен, что, поскольку executeOnce
возвращает функцию, вам действительно нужно вызвать executeOnce(options)()
в funA
.
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, но ваше решение не решает проблему, потому что использование записи через точку не позволяет мне передать имя объекта в качестве аргумента.
ты сейчас? если не ок! Пожалуйста, дайте мне знать!
Неа. Это все еще не работает. Он просто возвращает объект. Но когда я console.info(obj.options.spam:);
возвращает 4, а не обновленную 6, как следует.
вы знаете, что var executeOnce = (function (
опции) {...
не определено? потому что вы не передали аргумент функции executeOnce при первом запуске!
Разве executeOnce(options);
не переходит options
в var executeOnce
? Я подозреваю, что проблема, как вы предполагаете, заключается в этом процессе передачи аргумента от function funA(options)
к var executeOnce
, но я не уверен, как еще это написать?
так почему вы установили "вариант А"? почему вы не установили funA('options'); ? так что вы можете обновить свойство спама до 6
Я должен был установить options
, а не optionsA
. Это была ошибка, которую @Nate поймал выше. Я исправил это в своем посте, но это не было центральной проблемой.
Вы ошибаетесь в 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
в функцию возврата.
Я думаю, вы можете создать на одну функцию больше, чем вам нужно, но это ничего не сломает. Проблема, по-видимому, заключается в том, что возвращаемая функция (замыкание) не знает о 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 уже указал на проблему (и использовал только отладчик в своем уме). Хорошее шоу.
Почему ты звонишь
funA('optionsA');
. Я думаю этоfunA('options');