我在几个javascript文件中使用OLN作为一些基本的命名空间。"逻辑层次结构"其中一个文件是这样的:
-main.js
-somefile.js
-otherfile.js
-....
main.js管理所有页面需要的东西,但是根据加载的特定页面,可能会加载somefile.js或otherfile.js(或两者都不加载)。
在main.js中,语法如下:
main.js
var mainjs = {
someobjects: [baz],
// more stuff
}
根据加载的页面,加载其他javascript文件。他们可能会向列表中添加对象,如下所示:
somefile.js
let foo;
let bar;
$(function() {
console.log( " somefile.js ready!" );
mainjs.someobjects = mainjs.someobjects.concat([foo, bar])
}
如果我在页面加载后查看控制台,我可以看到在mainjs.someobjects
中,我有这3个对象。"baz"是已定义的,我添加的另外两个是"未定义的"。很好。
然而,当我后来从somefile.js
初始化这2个对象时(用户点击一些东西),然后在控制台中我可以看到foo
&bar
都是定义的。然而,在mainjs.someobjects
中,这两个对象仍然是未定义的。
我以为这些会作为参考传递,但显然我错了。基本上,我试图解决的问题是,我有几个不同的somefile.js
,这可能会创建不同的对象(数据表实际上),但他们获取数据(ajax调用)只有当包含它们的选项卡显示。然后我需要根据数据调整列的宽度。在填充数据表之前创建html是数据表的一个已知问题。为此需要调用table.columns.adjust()。
:
- 为什么我的变量在
mainjs
仍然未定义,我可以改变我的结构,这样当这些变量被分配给对象,他们实际上引用的对象? - 另一种方法来确保我的数据被调整。然而,我宁愿不建立一个完全不同的结构来实现这一目标。我想我可以将列调整委托给定义它们的低层文件…
我以为这些会作为参考传递,但显然我错了。
是的,JavaScript是一种纯粹的按值传递语言,而不是JavaScript本地模块("ESM")所做的。
听起来你想用ESM。在ESM中,当你导出一个模块级的绑定(松散地说,是变量),而另一个模块导入它时,另一个模块有一个只读live绑定将其链接到原始导出的。这意味着当导入它的模块使用它时,它会看到源绑定的当前值(而不是导出时的值)。
如果你用的是ESM的话:
export let foo;
export let bar;
// ...code here that asynchronously or periodically updates `foo` and/or `bar`...
然后是导入它们的模块:
import {foo, bar} from "./some-module.js";
…将通过这些活动绑定看到foo
和bar
的当前值。
如果您出于某种原因不想使用ESM,您可以导出具有foo
和bar
属性的对象,并让其他代码使用导出的对象。因为对象是稳定的(我们不会用不同的对象替换它),使用它的代码可以可靠地访问它的foo
和bar
属性并查看它们的当前值。
somefile.js
中:
const meaningfulName = {
foo: undefined, // Or some more meaningful initial value
bar: undefined, // Or some more meaningful initial value
};
$(function() {
console.log( " somefile.js ready!" );
// Just FWIW, I probably woudn't use an array for this, I'd use an object
mainjs.someobjects = mainjs.someobjects.concat(meaningfulName);
}
使用该对象的代码将使用其foo
和bar
属性,并始终看到它们的当前值。