【发布时间】:2016-08-12 17:07:05
【问题描述】:
我正在使用 Knockout.js 开发一个网站,但我的问题更笼统,所以不要专注于此。
我通过变量名引用对象本身,在本例中为viewModel,如下所示:
var viewModel = {
propA: "propA",
fnA: function () {
alert("I am " + viewModel.propA); //the same as this.propA
}
};
这样,当涉及到子对象和其他“花哨”的东西时,我不会遇到任何麻烦。
现在,我需要将另一个对象合并到我的 viewModel 中,但遇到了引用问题:
g_test = {}; //The way with this global variable is just for demonstration purposes
(function () {
var viewModel = {
propA: "propA",
fnA: function () {
alert("I am " + viewModel.propB);
}
};
g_test.vmA = viewModel;
})();
(function () {
var viewModel = {
propB: "propB",
fnB: function () {
alert("I am " + viewModel.propA);
}
}
/** merge viewModel "A" into viewModel "B" */
var vmA = g_test.vmA;
for (var key in vmA) {
if (vmA.hasOwnProperty(key)) {
viewModel[key] = vmA[key];
}
}
viewModel.fnA(); //I am undefined
viewModel.fnB(); //I am propA
})();
如您所见,fnB 知道propA,但fnA 不知道propB。
使用this 作为对viewModel 对象的引用但是可以完成这项工作。但我不想遍历我的整个对象并将每个viewModel 替换为this 或在需要时引入相应的“辅助变量”,因为这会花费我很多时间。另外,在我看来,这意味着不可能合并两个彼此没有双向知识的对象。
有没有一种有意义的方式让fnA 中的viewModel 变量指向viewModel "B" 而不必知道viewModel "B"?
【问题讨论】:
-
JavaScript 具有词法范围。在
fnA中更改viewModel的唯一方法是为其分配一个新值。但这在您的示例中是不可能的,因为viewModel是 IIFE 的本地对象。 -
用
this.propB替换viewModel.propB就可以了 -
使用
this就是答案。这就是它的用途。 -
另请注意,使用您的方法,
fnB函数会打印复制的propA,而不是原始值(因此它们可能具有不同的值)。 -
@MichaelBest 我知道,我想要那个副本。但 JAG 和您的建议真的是“微创”解决方案吗?这当然不是不可能的,但是如果可能的话,我真的很想避免大量的努力。不仅是出于努力的原因,而且还因为有可能以模块化方式向该对象/视图模型添加部件。
标签: javascript object knockout.js merge self-reference