gpt4 book ai didi

javascript - 通过 JavaScript 构造函数引入循环依赖

转载 作者:行者123 更新时间:2023-11-29 18:27:45 25 4
gpt4 key购买 nike

我有一个正在开发的 javascript 应用程序,我正在动态构建一个 Action 树,我发现自己处于一种奇怪的情况,想要有目的地引入循环依赖。在最初的非常 hacky 尝试之后,我发现 JavaScript 变量作用域实际上引入了一种非常合理的方法来解决这个问题。我仍然不是 JavaScript 专家,所以我想获得一些关于最佳实践的意见。这是一段工作代码:

var Step = function(title, instructions, action) {
this.title = ko.observable(title);
this.instructions = instructions;
this.action = action;
};

var Action = function(cancelText, cancelDescription, cancelStep, nextDescription, addText, addStep, continueText, continueStep) {
this.cancelText = cancelText;
this.cancelDescription = cancelDescription;
this.cancelStep = cancelStep;
this.nextDescription = nextDescription;
this.addText = addText;
this.addStep = addStep;
this.continueText = continueText;
this.continueStep = continueStep;
};

var PersonalStep = new Step(
"Contact Information",
"How can we contact you about your awesome assortment of vehicles? Fill out the form below",
new Action(null, null, null, null, null, null, null, null)
);

var AddVehicleStep = new Step(
"Additional Vehicle",
"You have another car? Great, tell us about it too!",
new Action("Cancel",
"No, nevermind about this vehicle.",
PersonalStep,
"Add another vehicle?",
"+ Add",
AddVehicleStep, // This is the weird bit to me
"No, continue on",
PersonalStep)
);

var VehicleStep = new Step(
"Vehicle Details",
"Tell us about your primary vehicle by filling out the form below.",
new Action(null, null, null,
"Add another vehicle?",
"+ Add",
AddVehicleStep,
"No, continue on",
PersonalStep)
);

因此,实际上,当用户在表单上选择“添加”操作时,AddVehicleStep 可以连续添加额外的车辆。在大多数语言中(无论如何我都熟悉),AddVehicleStep 变量无法从其自己的构造函数中进行解析。这对我来说很奇怪,我想更多地了解 JS 的这个习语。有没有更好的方法来动态生成这样的对象树?

这也让我开始思考,我一直有意以相反的顺序声明我的步骤变量,这样它们就可以解析了。关于在其自己的构造函数中引用变量的发现使我相信这是没有必要的。但我刚刚对其进行了测试,如果我在 VehicleStep 之后移动 AddVehicleStep 变量,VehicleStep 将为其 action.addStep 获取 null。有没有办法绕过这个限制并让我的变量以任何顺序声明?使用空白声明然后设置它们会起作用吗?例如

var a;
var b;

var a = new Step(b);
var b = new Step(b);
// a should now have the full instantiated object of b within it, right?
// (provided the step constructor assigned it, of course)

这可能已经在其他地方得到了回答,我只是没有找到提出它的关键词...

此外,我将这些步骤用作 Knockout.js 应用程序的一部分,该应用程序本质上是实现对话框/表单向导 - 我希望示例代码能够独立解决难题,但以防万一您感到好奇。

更新昨晚我在 JS fiddle 中工作。事实证明,在 jsfiddle 的后续运行之间如何处理 js 内存,导致它在我一直在使用的特定窗口(Chrome,最新版本)中工作。但是,在新窗口或新浏览器中打开它时,它会停止工作。

真正奇怪的部分是我无法在任何浏览器中复制该行为。也许我的一个编辑有不同的声明并以某种方式将它存储在内存中。我真希望我能复制它,只是为了证明我没有疯......

感谢您的帮助!

最佳答案

由于步骤可以包含引用同一步骤的操作,我认为最简单的方法是让自己能够在构建步骤后添加操作。所以,像这样。

var Step = function(title, instructions, action) {
this.title = ko.observable(title);
this.instructions = instructions;
if (action === undefined)
this.action = null; //action was not passed
else
this.action = action;
};

//set the action after constructor invocation
Step.prototype.SetAction = function(action) {
this.action = action;
};

var AddVehicleStep = new Step(
"Additional Vehicle",
"You have another car? Great, tell us about it too!"
);
//AddVehicleStep is now instantiated with a new Step,
// so we can now set its action refering to that step
AddVehicleStep.SetAction(new Action("Cancel",
"No, nevermind about this vehicle.",
PersonalStep,
"Add another vehicle?",
"+ Add",
AddVehicleStep, // This is the weird bit to me
"No, continue on",
PersonalStep));

还是见鬼,忘了方法,直接做

AddVehicleStep.action = new Action(...);

但是如果您开始这样做,您将无法始终确定在设置操作时会发生什么而无需重写代码。

为什么要这样做?您必须了解操作顺序以及它如何影响这里的事情。

a = b(c(a))

操作顺序是

  1. c(a) -> result1
  2. b(result1) -> result2
  3. a获取result2
  4. 的值

假设a(在局部范围内)之前没有被赋值,那么c(a)等同于c(undefined)

关于javascript - 通过 JavaScript 构造函数引入循环依赖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11406407/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com