ES6 ส่งออกค่าทั้งหมดจากวัตถุ


112

สมมติว่าฉันมีโมดูล ( ./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

ซึ่งไม่หยุดนิ่ง

เป็นไปได้ไหมที่จะส่งออกค่าทั้งหมดจากวัตถุ?


6
ไม่ได้เนื่องจากค่าที่คำนวณแบบไดนามิกไม่สามารถส่งออกแบบคงที่
Bergi

@Bergi ฉันสงสัยว่าเป็นไปได้ไหมที่จะทำให้ค่าคงที่ในบางครั้ง ฉันกำลังคิดว่าถ้าคุณใช้interface { a: number, b: number, c: number }? ในทางทฤษฎีมันควรจะเป็นไปได้ใช่มั้ย?
Fleuv

1
@Fleuv export const {a, b, c} = valuesเป็นไวยากรณ์ที่แม่นยำในการประกาศอินเทอร์เฟซแบบคงที่
Bergi

คำตอบ:


39

ดูเหมือนจะไม่เป็นเช่นนั้น อ้างจากโมดูล ECMAScript 6: ไวยากรณ์สุดท้าย :

คุณอาจสงสัยว่าทำไมเราถึงต้องมีชื่อการส่งออกถ้าเราสามารถส่งออกวัตถุเริ่มต้นได้ (เช่น CommonJS) คำตอบคือคุณไม่สามารถบังคับใช้โครงสร้างแบบคงที่ผ่านวัตถุและสูญเสียข้อดีที่เกี่ยวข้องทั้งหมด (อธิบายไว้ในหัวข้อถัดไป)


3
คุณสามารถใช้อาร์เรย์ได้หรือไม่หากมีคู่ชื่อ - ค่า
Kevin Suttle

79

ฉันไม่สามารถแนะนำวิธีแก้ปัญหานี้ได้จริงๆ แต่มันใช้งานได้ แทนที่จะส่งออกอ็อบเจ็กต์คุณใช้ชื่อเอ็กซ์พอร์ตสมาชิกแต่ละคน ในไฟล์อื่นให้อิมพอร์ตการเอ็กซ์พอร์ตที่มีชื่อของโมดูลแรกลงในอ็อบเจ็กต์และเอ็กซ์พอร์ตอ็อบเจ็กต์นั้นเป็นค่าเริ่มต้น นอกจากนี้ยังส่งออกการส่งออกที่มีชื่อทั้งหมดจากโมดูลแรกโดยใช้export * from './file1';

ค่า / value.js

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

export {a, b, c};

ค่า / 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

2
ทำไมคุณไม่แนะนำสิ่งนี้
jsdario

2
อาจเป็นเพราะการรักษานั้นแย่กว่าความเจ็บป่วย (เว้นแต่คุณจะเขียนห้องสมุดที่ใช้งานได้ทั่วไปและคุณจู้จี้จุกจิกเกี่ยวกับการนำเข้า)
machineghost

ใช่นั่นเป็นบทสรุปที่ดี เป็นเทคนิคที่ฉันใช้ครั้งหนึ่งในห้องสมุดเพื่อลดความสิ้นเปลือง ฉันคิดว่าการจัดการการส่งออกภายในไฟล์เดียวจะดีกว่าแม้ว่าจะเหมาะกับผู้เขียนห้องสมุดมากกว่าก็ตาม ผลลัพธ์คือความลึกของโมดูลที่น้อยลงสำหรับผู้ใช้
ryanjduffy

ฉันค่อนข้างชอบวิธีแก้ปัญหานี้ แต่ควรเป็น "./value" แทน "./values" ในค่า / index.js ใช่ไหม
Jan Paepke

1
ฉันไม่คิดว่านี่คือคำตอบจริงๆเพราะถ้าฉันส่งออกไปแล้ว{ a, b, c }ทำไมฉันต้องส่งออกอีกครั้ง คำถามที่แท้จริงคือจะเกิดอะไรขึ้นถ้าฉันมีconst obj = { a, b, c }และฉันจะส่งออกสมาชิกทั้งหมดของ obj ได้หรือไม่? ฉันเดาว่าคำตอบคือไม่
windmaomao

14

ลองใช้วิธีแก้ปัญหาที่น่าเกลียด แต่ใช้งานได้:

// 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);

12

ฉันต้องทำสิ่งนี้สำหรับไฟล์ config

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 ในใจคุณ


34
คุณควรจะทำได้import config from './config';
Matt Hamann

4
export const a = 1;
export const b = 2;
export const c = 3;

สิ่งนี้จะใช้งานได้กับBabel ที่เปลี่ยนแปลงในวันนี้และควรใช้ประโยชน์จากประโยชน์ทั้งหมดของโมดูล ES2016 เมื่อใดก็ตามที่คุณลักษณะนั้นมาถึงในเบราว์เซอร์

คุณยังสามารถเพิ่มexport default {a, b, c};ซึ่งจะช่วยให้คุณสามารถนำเข้าค่าทั้งหมดเป็นวัตถุที่* asไม่มีเช่นimport myModule from 'my-module';

แหล่งที่มา:


3

ฉันขอแนะนำสิ่งต่อไปนี้คาดว่าจะมี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


3

ทุกคำตอบต้องมีการเปลี่ยนแปลงงบนำเข้า

หากคุณต้องการที่จะใช้:

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


3

คุณสามารถทำอะไรโง่ ๆ ได้มากมายด้วยจาวาสคริปต์ ฉันจะทิ้งคำพูดนี้ไว้ที่นี่จากหนังสือ YDKJS

ใส่คำอธิบายภาพที่นี่

หน้าที่กล่าวถึงของหนังสือ ->

https://books.google.com.tr/books? X & ved = 2ahUKEwi4qseXyrDdAhUS-6QKHZYTAEQQ6AEwAHoECAEQAQ # v = onepage & q = JS% 20engine% 20cannot% 20statically% 20analyze% 20the% 20contents% 20of% 20plain% 20object & f = false


2

ส่งออกตัวแปรแต่ละตัวจากไฟล์ตัวแปรของคุณ จากนั้นอิมพอร์ตด้วย * เช่นเดียวกับในไฟล์อื่นของคุณและเอ็กซ์พอร์ตเป็นค่าคงที่จากไฟล์นั้นจะให้อ็อบเจ็กต์ไดนามิกที่มีการเอ็กซ์พอร์ตที่มีชื่อจากไฟล์แรกที่เป็นแอ็ตทริบิวต์บนอ็อบเจ็กต์ที่ส่งออกจากไฟล์ที่สอง

ตัวแปร js

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

อื่น ๆ js

import * as vars from './Variables';

export const Variables = vars;

Third.js

import { Variables } from './Other';

Variables.var2 === 'second'

คุณช่วยเพิ่มคำอธิบายได้ไหม
Nilambar Sharma
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.