Javascript 命名空间 - 从对象文字表示法 (OLN) 更新数组值
Javascript namespacing - updating an an array value from an object literal notation (OLN)
我在几个 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”已定义,我添加的另外 2 个是“未定义”。没关系。
但是,当我稍后从 somefile.js
初始化这两个对象时(用户单击某些内容),然后在控制台中我可以看到 foo
和 bar
都已定义。但是,在 mainjs.someobjects
中,这 2 个对象仍未定义。
我以为那些会作为参考传递,但显然我错了。基本上我要解决的问题是我有几个不同的 somefile.js
可能会创建不同的对象(实际上是 dataTables)但它们仅在包含它们的选项卡时才获取数据(ajax 调用)显示。然后我需要根据数据调整列宽。当 html 在填充数据表之前创建时,数据表的一个已知问题。为此需要调用 table.columns.adjust()。
所以:
- 为什么我在
mainjs
中的变量仍然未定义,我可以更改我的结构,以便当这些变量稍后分配给对象时,它们实际上引用了该对象?
- 或者确保我的数据表得到调整的另一种方法。但是,我宁愿不必构建一个完全不同的结构来实现这一点。我想我可以将列调整委托给定义它们的较低级别的文件...
I thought those would be passed as reference, but apparently I was wrong.
是的,JavaScript 是一种纯粹的按值传递语言,不同于 JavaScript 本机模块(“ESM”)所做的事情。
我觉得您想使用 ESM。在 ESM 中,当您导出模块级 binding(松散地称为“变量”)并且另一个模块导入它时,另一个模块具有 只读 live binding 将其链接到原始导出的。这意味着当导入它的模块使用它时,它会看到源绑定的当前值(而不是导出时的值)。
因此,如果您正在使用 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
属性,并始终看到它们的当前值。
我在几个 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”已定义,我添加的另外 2 个是“未定义”。没关系。
但是,当我稍后从 somefile.js
初始化这两个对象时(用户单击某些内容),然后在控制台中我可以看到 foo
和 bar
都已定义。但是,在 mainjs.someobjects
中,这 2 个对象仍未定义。
我以为那些会作为参考传递,但显然我错了。基本上我要解决的问题是我有几个不同的 somefile.js
可能会创建不同的对象(实际上是 dataTables)但它们仅在包含它们的选项卡时才获取数据(ajax 调用)显示。然后我需要根据数据调整列宽。当 html 在填充数据表之前创建时,数据表的一个已知问题。为此需要调用 table.columns.adjust()。
所以:
- 为什么我在
mainjs
中的变量仍然未定义,我可以更改我的结构,以便当这些变量稍后分配给对象时,它们实际上引用了该对象? - 或者确保我的数据表得到调整的另一种方法。但是,我宁愿不必构建一个完全不同的结构来实现这一点。我想我可以将列调整委托给定义它们的较低级别的文件...
I thought those would be passed as reference, but apparently I was wrong.
是的,JavaScript 是一种纯粹的按值传递语言,不同于 JavaScript 本机模块(“ESM”)所做的事情。
我觉得您想使用 ESM。在 ESM 中,当您导出模块级 binding(松散地称为“变量”)并且另一个模块导入它时,另一个模块具有 只读 live binding 将其链接到原始导出的。这意味着当导入它的模块使用它时,它会看到源绑定的当前值(而不是导出时的值)。
因此,如果您正在使用 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
属性,并始终看到它们的当前值。