`export const` so với` export default` trong ES6


204

Tôi đang cố gắng xác định xem có sự khác biệt lớn nào giữa hai điều này không, ngoài việc có thể nhập khẩu bằng export defaultcách thực hiện:

import myItem from 'myItem';

Và sử dụng export consttôi có thể làm:

import { myItem } from 'myItem';

Tôi tự hỏi nếu có bất kỳ sự khác biệt và / hoặc trường hợp sử dụng khác hơn này.


1
Sử dụng constsẽ làm cho định danh chỉ đọc. Vì vậy, trong trường hợp giá trị nguyên thủy, bạn có thể coi đó là bất biến. Lưu ý rằng bản thân giá trị không phải là bất biến, vì vậy các đối tượng, mảng, v.v có thể được thay đổi - chỉ không được gán lại.
spm Hurzzz

4
@spm Hurzzz: FWIW, các ràng buộc nhập khẩu cũng không thay đổi, giống như const.
Felix Kling

cảm ơn vì đã làm rõ @FelixKling, không biết điều đó
spm Hurzzz

@FelixKling: Ít nhất là từ bên ngoài. Họ có thể không phải là mặc dù, xuất khẩu có thể được thay đổi.
Bergi

@Bergi: đúng, đó là lý do tại sao tôi nói ràng buộc nhập khẩu ;)
Felix Kling

Câu trả lời:


327

Đó là xuất khẩu có tên so với xuất khẩu mặc định. export constlà một xuất khẩu có tên xuất khẩu một tuyên bố const hoặc khai báo.

Để nhấn mạnh: điều quan trọng ở đây là exporttừ khóa constđược sử dụng để khai báo khai báo const hoặc khai báo. exportcũng có thể được áp dụng cho các khai báo khác như khai báo lớp hoặc hàm.

Xuất mặc định ( export default)

Bạn có thể có một xuất mặc định cho mỗi tệp. Khi bạn nhập, bạn phải chỉ định một tên và nhập như vậy:

import MyDefaultExport from "./MyFileWithADefaultExport";

Bạn có thể đặt tên này bất kỳ bạn thích.

Xuất khẩu có tên ( export)

Với xuất khẩu được đặt tên, bạn có thể có nhiều xuất khẩu được đặt tên cho mỗi tệp. Sau đó, nhập các mặt hàng xuất khẩu cụ thể mà bạn muốn bao quanh trong niềng răng:

// ex. importing multiple exports:
import { MyClass, MyOtherClass } from "./MyClass";
// ex. giving a named import a different name by using "as":
import { MyClass2 as MyClass2Alias } from "./MyClass2";

// use MyClass, MyOtherClass, and MyClass2Alias here

Hoặc có thể sử dụng mặc định cùng với nhập khẩu có tên trong cùng một tuyên bố:

import MyDefaultExport, { MyClass, MyOtherClass} from "./MyClass";

Nhập không gian tên

Cũng có thể nhập mọi thứ từ tệp trên một đối tượng:

import * as MyClasses from "./MyClass";
// use MyClasses.MyClass, MyClasses.MyOtherClass and MyClasses.default here

Ghi chú

  • Cú pháp ưu tiên xuất mặc định là ngắn gọn hơn một chút vì trường hợp sử dụng của chúng là phổ biến hơn ( Xem phần thảo luận tại đây ).
  • Xuất khẩu mặc định thực sự là xuất khẩu có tên với tên defaultđể bạn có thể nhập nó với nhập khẩu có tên:

    import { default as MyDefaultExport } from "./MyFileWithADefaultExport";

24

export defaultảnh hưởng đến cú pháp khi nhập "vật" đã xuất, khi cho phép nhập, bất cứ thứ gì đã được xuất, bằng cách chọn tên trong importchính nó, bất kể tên đó là gì khi được xuất, đơn giản vì nó được đánh dấu là "mặc định".

Một trường hợp sử dụng hữu ích, mà tôi thích (và sử dụng), cho phép xuất một hàm ẩn danh mà không cần phải đặt tên rõ ràng và chỉ khi hàm đó được nhập, nó phải được đặt tên:


Thí dụ:

Xuất 2 chức năng, một là default:

export function divide( x ){
    return x / 2;
}

// only one 'default' function may be exported and the rest (above) must be named
export default function( x ){  // <---- declared as a default function
    return x * x;
}

Nhập các chức năng trên. Tạo một tên cho defaultmột:

// The default function should be the first to import (and named whatever)
import square, {divide} from './module_1.js'; // I named the default "square" 

console.log( square(2), divide(2) ); // 4, 1

Khi {}cú pháp được sử dụng để nhập khẩu một hàm (hoặc biến) thì có nghĩa là bất cứ điều gì được nhập khẩu đã được đã được đặt tên khi xuất khẩu, vì vậy người ta phải nhập nó bằng chính xác cùng tên, nếu không nhập khẩu sẽ không làm việc.


Ví dụ đáng ghét:

  1. Chức năng mặc định phải là đầu tiên để nhập

    import {divide}, square from './module_1.js
  2. divide_1đã không được xuất khẩu module_1.js, do đó sẽ không có gì được nhập khẩu

    import {divide_1} from './module_1.js
  3. squaređã không được xuất khẩu module_1.js, bởi vì {}nói cho công cụ tìm kiếm rõ ràng chỉ xuất khẩu được đặt tên .

    import {square} from './module_1.js

Nó không có nghĩa là nó xuất khẩu một điều duy nhất. Bạn có thể có nhiều tên được đặt và một mặc định trong cùng một mô-đun. Mặc định đơn giản có nghĩa là chính xác - đó là xuất mặc định nếu bạn không chỉ định tên khi nhập, tức là import something fromthay vì import { somethingNamed } from.
Andris

Tôi cũng đã học từ tiếng Anh mới ở đây: "Erroneous" +1 cho điều đó
Yuval Levy

12

Lưu ý nhỏ: Vui lòng xem xét rằng khi bạn nhập từ xuất mặc định, việc đặt tên hoàn toàn độc lập. Điều này thực sự có tác động đến tái cấu trúc.

Giả sử bạn có một lớp Foonhư thế này với một lần nhập tương ứng:

export default class Foo { }

//the name 'Foo' could be anything, since it's just an
//identifier for the default export
import Foo from './Foo'

Bây giờ nếu bạn cấu trúc lại Foolớp của mình thành Barvà đổi tên tệp, hầu hết các IDE sẽ KHÔNG chạm vào mục nhập của bạn. Vì vậy, bạn sẽ kết thúc với điều này:

export default class Bar { }

//the name 'Foo' could be anything, since it's just an
//identifier for the default export.
import Foo from './Bar'

Đặc biệt là trong Bản mô tả, tôi thực sự đánh giá cao xuất khẩu có tên và tái cấu trúc đáng tin cậy hơn. Sự khác biệt chỉ là thiếu defaulttừ khóa và dấu ngoặc nhọn. Btw này cũng ngăn bạn thực hiện một lỗi đánh máy trong quá trình nhập của bạn vì bạn đã kiểm tra kiểu bây giờ.

export class Foo { }

//'Foo' needs to be the class name. The import will be refactored
//in case of a rename!
import { Foo } from './Foo'

2
" 'Foo' cần phải là tên lớp. " - không! Bạn có thể dễ dàng làm import { Foo as Anything } from …như bạn có thể làm import Anything from …với xuất mặc định.
Bergi

Rằng bạn có thể đổi tên nó với một asthực sự không phải là điểm trong bình luận nguồn đó. Cảm ơn các downvote; p
Philipp Sumi

1
Tôi đã không downvote, tuy nhiên tôi không chắc liệu lập luận đó có thuyết phục hay không. Tôi không biết liệu tôi có muốn đổi tên IDE của mình để đổi tên tất cả các lần nhập hay không khi tái cấu trúc một mô-đun duy nhất, đó chính xác là mô-đun hóa về :-) Và dường như đó là một "vấn đề" của IDE không phải là lý do để chọn kiểu xuất ...
Bergi

Tôi đồng ý rằng tôi sử dụng xuất khẩu có tên vì lợi ích của nhà phát triển UX ở đây - nhưng sau đó, bạn có thể lập luận rằng Typecript per se là tất cả về điều đó. Tôi thường xuyên cấu trúc lại và cho rằng tôi thường có một lớp (trong trường hợp của tôi: Thành phần phản ứng) cho mỗi tệp, tôi hoàn toàn muốn các mục nhập theo một thành phần được đổi tên để không tạo ra ngắt kết nối. Tất nhiên, điều này có thể có hoặc không có ý nghĩa tùy thuộc vào từng nhà phát triển.
Philipp Sumi

Tôi tìm thấy một bài báo nói điều tương tự. Có lẽ một vị trí hợp lý có thể là: chúng ta nên sử dụng export defaultđể xuất đối tượng chính của dự án, đặc biệt là từ các gói npm (nó thay thế a module.exports =). Nhưng, nội bộ trong một dự án, tốt hơn là chỉ sử dụng xuất khẩu có tên.
Paleo

7

Từ tài liệu :

Xuất khẩu được đặt tên là hữu ích để xuất khẩu một số giá trị. Trong quá trình nhập, người ta sẽ có thể sử dụng cùng tên để chỉ giá trị tương ứng.

Liên quan đến xuất mặc định, chỉ có một xuất mặc định duy nhất cho mỗi mô-đun. Xuất khẩu mặc định có thể là một hàm, một lớp, một đối tượng hoặc bất cứ thứ gì khác. Giá trị này được coi là giá trị xuất "chính" vì nó sẽ là đơn giản nhất để nhập.


0

Khi bạn đặt mặc định, nó được gọi là xuất mặc định. Bạn chỉ có thể có một lần xuất mặc định cho mỗi tệp và bạn có thể nhập tệp đó vào một tệp khác với bất kỳ tên nào bạn muốn. Khi bạn không đặt mặc định, nó được gọi là xuất khẩu, bạn phải nhập nó vào một tệp khác sử dụng cùng tên với dấu ngoặc nhọn bên trong nó.


0

Tôi gặp vấn đề là trình duyệt không sử dụng es6.

Tôi đã sửa nó bằng:

 <script type="module" src="index.js"></script>

Mô-đun loại cho trình duyệt sử dụng ES6.

export const bla = [1,2,3];

import {bla} from './example.js';

Sau đó, nó sẽ làm việc.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.