【问题标题】:ES6 export all values from objectES6 从对象中导出所有值
【发布时间】:2015-04-24 09:42:40
【问题描述】:

假设我有一个模块 (./my-module.js),它的对象应该是它的返回值:

let values = { a: 1, b: 2, c: 3 }

// "export values" results in SyntaxError: Unexpected token

所以我可以像这样导入它们:

import {a} from './my-module'           // a === 1
import * as myModule from './my-module' // myModule.a === 1

我发现的唯一方法是对导出进行硬编码:

export let a = values.a
export let b = values.b
export let c = values.c
// or:
export let {a, b, c} = values

这不是动态的。

是否可以从一个对象中导出所有值?

【问题讨论】:

  • 否,因为动态计算的值不能静态导出。
  • @Bergi,我想知道是否有可能以某种方式使值静态化。我在想如果你使用interface { a: number, b: number, c: number } 会怎样?理论上应该是可以的吧?
  • @Fleuv export const {a, b, c} = values 正是声明该静态接口的语法

标签: module export ecmascript-6


【解决方案1】:

我不能真正推荐这个 solution 解决方法,但它确实有效。您不是导出对象,而是使用命名导出每个成员。在另一个文件中,将第一个模块的命名导出导入对象并将该对象导出为默认值。还使用export * from './file1';从第一个模块导出所有命名的导出

values/value.js

let a = 1;
let b = 2;
let c = 3;

export {a, b, c};

values/index.js

import * as values from './value';

export default values;
export * from './value';

index.js

import values, {a} from './values';

console.log(values, a); // {a: 1, b: 2, c: 3} 1

【讨论】:

  • 你为什么不推荐这个?
  • 也许是因为治疗比疾病更糟糕(除非你正在编写一个公共消费库并且你对它的导入方式非常挑剔)?
  • 是的,这是一个很好的总结。这是我曾经在图书馆中使用过的一种技术,以简化可消费性。我认为最好在单个文件中管理导出,即使库作者需要做更多的工作。结果是用户的模块深度减少了一个。
  • 我很喜欢这个变通办法,但它应该是 './value' 而不是 values/index.js 中的 './values',对吧?
  • 我真的不认为这是答案,因为如果我已经导出{ a, b, c },为什么我需要再次导出?真正的问题是,如果我只有 const obj = { a, b, c } 并且可以导出 obj 的所有成员怎么办?我想答案是否定的。
【解决方案2】:

似乎并非如此。引用ECMAScript 6 modules: the final syntax:

您可能想知道——如果我们可以简单地默认导出对象(如 CommonJS),为什么还需要命名导出?答案是您不能通过对象强制执行静态结构并失去所有相关优势(将在下一节中介绍)。

【讨论】:

  • 如果数组有名称-值对,你能用吗?
【解决方案3】:

我只是需要为配置文件执行此操作。

var config = {
    x: "CHANGE_ME",
    y: "CHANGE_ME",
    z: "CHANGE_ME"
}

export default config;

你可以这样做

import { default as config } from "./config";

console.log(config.x); // CHANGE_ME

请注意,这是使用 Typescript。

【讨论】:

  • 你应该可以做到import config from './config';
【解决方案4】:

试试这个丑陋但可行的解决方案:

// use CommonJS to export all keys
module.exports = { a: 1, b: 2, c: 3 };

// import by key
import { a, b, c } from 'commonjs-style-module';
console.log(a, b, c);

【讨论】:

    【解决方案5】:

    我建议如下,让我们期待一个 module.js

    const values = { a: 1, b: 2, c: 3 };
    
    export { values }; // you could use default, but I'm specific here
    

    然后你可以在 index.js 中做:

    import { values } from "module";
    
    // directly access the object
    console.log(values.a); // 1
    
    // object destructuring
    const { a, b, c } = values; 
    console.log(a); // 1
    console.log(b); // 2
    console.log(c); // 3
    
    // selective object destructering with renaming
    const { a:k, c:m } = values;
    console.log(k); // 1
    console.log(m); // 3
    
    // selective object destructering with renaming and default value
    const { a:x, b:y, d:z = 0 } = values;
    console.log(x); // 1
    console.log(y); // 2
    console.log(z); // 0
    

    更多析构对象示例:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Object_destructuring

    【讨论】:

      【解决方案6】:

      为什么不直接对对象进行命名导出:

      let values = { a: 1, b: 2, c: 3 }
      export { values }
      

      export let values = { a: 1, b: 2, c: 3 }
      

      然后在您需要的地方进行命名导入:

      import { values } from './my-module'
      
      let foo = values.a
      let { a, b, c } = values
      

      import { values as myModule } from './my-module'
      
      let foo = myModule.a
      let { a, b, c } = myModule
      

      也可以进行默认导出:

      let values = { a: 1, b: 2, c: 3 }
      export default values 
      

      export default { a: 1, b: 2, c: 3 }
      

      然后消费它:

      import whateverIcallIt from './my-Module'
      
      let foo = whateverIcallIt.a
      let {a, b, c } = whateverIcallIt
      

      如果你想导出一堆单独的值,比如说一堆常量,你可以:

      export const a = 1
      export const b = 2
      //...
      

      甚至

      export const a = 1,
                   b = 2,
                   c = 3,
      //...
      

      然后单独导入:

      import { a, b, c } from './my-module'
      

      【讨论】:

        【解决方案7】:
        export const a = 1;
        export const b = 2;
        export const c = 3;
        

        这将在今天与Babel transforms 一起工作,并且只要该功能实际登陆浏览器,就可以利用 ES2016 模块的所有优势。

        您还可以添加export default {a, b, c};,这将允许您将所有值导入为不带* as 的对象,即import myModule from 'my-module';

        来源:

        【讨论】:

          【解决方案8】:
          【解决方案9】:

          每个答案都需要更改导入语句。

          如果你想能够使用:

          import {a} from './my-module'           // a === 1
          import * as myModule from './my-module' // myModule.a === 1
          

          在问题中,在您的 my-module 中,您拥有需要在一个对象中导出的所有内容(这可能很有用,例如,如果您想使用 Joi 或 JSON Schema 验证导出的值)然后您的 my-module必须是:

          let values = { a: 1, b: 2, c: 3 }
          let {a, b, c} = values;
          export {a, b, c};
          

          或者:

          let values = { a: 1, b: 2, c: 3 }
          export let {a, b, c} = values;
          

          不漂亮,但它可以编译成你需要的东西。

          见:Babel example

          【讨论】:

          • 问题中已经提到了这个方法(在“硬编码”下)
          【解决方案10】:

          从变量文件中导出每个变量。然后像在其他文件中一样使用 * 导入它们并从该文件中导出为常量,将为您提供一个动态对象,其中第一个文件中的命名导出是从第二个文件中导出的对象的属性。

          Variables.js

          export const var1 = 'first';
          export const var2 = 'second':
          ...
          export const varN = 'nth';
          

          其他.js

          import * as vars from './Variables';
          
          export const Variables = vars;
          

          第三个.js

          import { Variables } from './Other';
          
          Variables.var2 === 'second'
          

          【讨论】:

          • 能否请您也添加解释?
          猜你喜欢
          • 2016-11-16
          • 2016-09-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-06-27
          • 2021-06-03
          • 2021-06-13
          相关资源
          最近更新 更多