Javascript如何处理导出的模块级变量?

时间:2019-02-03 22:19:26

标签: javascript

在Javascript应用中,我有一个定义为模块的服务,例如在services/MyService.js中。

说服务看起来像这样:

let lastUpdated;

function update() {
  lastUpdated = new Date();
}

lastUpdated = new Date();

export default {
  update,
  lastUpdated
}

另一个文件index.js导入了此服务:

import MyService from "./services";

console.log(MyService.lastUpdated);
setTimeout(() => {
  MyService.update();
  console.log(MyService.lastUpdated);
}, 1000)

我认为MyService.lastUpdated会在调用MyService.update()之后发生变化,但不会改变。导入变量后,它是否是指向初始Date对象的指针?如果是这样,我如何更新它以便可以在其他位置访问“实时”变量?

2 个答案:

答案 0 :(得分:3)

export default { update, lastUpdated }导出具有属性updatelastUpdated对象。对于您要解决的问题,由于以下代码中的lastUpdated未被更改的相同原因,该对象的lastUpdated属性未被更改:

let lastUpdated;
function update() {
  lastUpdated = new Date();
}
lastUpdated = new Date();
const MyService = {
  update,
  lastUpdated
};

console.log(MyService.lastUpdated);
setTimeout(() => {
  MyService.update();
  console.log(MyService.lastUpdated);
}, 1000)

您要重新分配名为lastUpdated变量,但是您永远都不会突变已导出的对象,因此您不会看到调用update后在另一个模块中检查对象时更改。

您可以导出要突变的对象:

// MyService.js
function update() {
  console.log("upd");
  obj.lastUpdated = new Date();
}
const obj = {
  update,
  lastUpdated: new Date()
};

export default obj;

尽管可能不建议这样做,但另一个选择是使用命名导出而不是对象的默认导出。在一个模块中 重新分配已命名的导出将导致该导出在其他位置导入的更改:

// MyService.js
let lastUpdated;
function update() {
  console.log("upd");
  lastUpdated = new Date();
}
lastUpdated = new Date();
export { update, lastUpdated };

// index.js
import { update, lastUpdated } from "./MyService";
console.log(lastUpdated);
setTimeout(() => {
  update();
  console.log(lastUpdated);
}, 1500);

(但是,重新分配命名的出口通常会使代码更难于理解,而lint有时会禁止这样做)

答案 1 :(得分:0)

在这种意义上,变量不能实时更新。如果要使用ES6,您想要的是使用lastUpdated变量的getter和setter声明一个类:

export default class MyService {
    // Member
    constructor() {
        this.lastUpdated = new Date();
    }

    // Method
    update() {
        this.lastUpdated = new Date();
    }
}

然后,您可以使用MyService创建类new MyService()的新实例,然后按如下方式访问lastUpdated变量:

import MyService from "./services";

const myService = new MyService();

// Get current timestamp
console.log(myService.lastUpdated);

window.setTimeout(() => {
    // Update timestamp
    myService.update();

    // Get updated timestamp
    console.log(myService.lastUpdated);
}, 1000);