2016-09-01 22 views
8

Tôi hiểu rằng với việc xuất mô-đun ES6, một ràng buộc diễn ra giữa những gì được xuất và những gì được nhập, để khi biến được xuất thay đổi, biến được nhập sẽ chứng minh thay đổi đó.Có sự khác biệt nào giữa `xuất mặc định x` và` xuất {x làm mặc định} `không?

Tuy nhiên, tôi cũng đã đọc rằng biến được nhập chỉ mang ràng buộc với biến được xuất trong một số trường hợp nhất định.

câu hỏi cụ thể của tôi là liệu có sự khác biệt trong cách các biến xuất khẩu đang bị ràng buộc trong hai kịch bản sau đây ...

// Scenario #1 
let a = 5; 
export default a; 

// Scenario #2 
let a = 5; 
export { a as default }; 
+0

r phấn khởi: [Sự khác nhau giữa việc nhập khẩu một biểu thức hàm hoặc khai báo hàm từ một mô-đun ES6 là gì?] (http://stackoverflow.com/q/35223111/1048572) – Bergi

Trả lời

8

Chúng không giống nhau trong trường hợp chung, mặc dù chúng có thể hoạt động giống nhau trong trường hợp các hàm và lớp.

let a = 4; 
export default a; 

tương đương với

let a = 4; 
let *default* = a; 
export {*default* as default}; 

nghĩa là

let a = 4; 
export default a; 

a = 5; 

sẽ rời 4 như giá trị xuất khẩu, mặc dù a bên trong mô-đun đã thay đổi, trong khi export {a as default}; sẽ làm cho giá trị xuất khẩu 5.

Các ECMAScript đặc tả định nghĩa ba dạng khác nhau của export default, với một số ví dụ trong bảng này http://www.ecma-international.org/ecma-262/7.0/#table-42 và trong tờ khai cú pháp chính cho xuất khẩu: http://www.ecma-international.org/ecma-262/7.0/#sec-exports

export default HoistableDeclaration 
export default ClassDeclaration 
export default [lookahead ∉ { function, class }] AssignmentExpression; 

với HoistableDeclaration trong bản đồ trường hợp này để khai báo hàm và khai báo trình tạo.

Nếu chúng ta nhìn vào spec nơi nó định nghĩa các ánh xạ tên biến trong tập tin, để tên xuất khẩu, http://www.ecma-international.org/ecma-262/7.0/#sec-exports-static-semantics-exportentries

ExportDeclaration: export default HoistableDeclaration 
    Let names be BoundNames of HoistableDeclaration. 
    Let localName be the sole element of names. 
    Return a new List containing the Record {[[ModuleRequest]]: null, 
    [[ImportName]]: null, [[LocalName]]: localName, [[ExportName]]: "default"}. 

ExportDeclaration: export default ClassDeclaration 
    Let names be BoundNames of ClassDeclaration. 
    Let localName be the sole element of names. 
    Return a new List containing the Record {[[ModuleRequest]]: null, 
    [[ImportName]]: null, [[LocalName]]: localName, [[ExportName]]: "default"}. 

ExportDeclaration: export default AssignmentExpression; 
    Let entry be the Record {[[ModuleRequest]]: null, [[ImportName]]: null, 
    [[LocalName]]: "*default*", [[ExportName]]: "default"}. 
    Return a new List containing entry. 

    NOTE 
    "*default*" is used within this specification as a synthetic name for anonymous default export values. 

BoundNames đây trả về tên của hàm hoặc lớp đều đạt như giá trị, vì vậy trong hai trường hợp đầu tiên

export default function fn(){} 
// or 
export default function* fn(){} 
// or 
export default class cls {} 

sẽ xuất kết buộc trực tiếp cho các biến fn hoặc cls.

Bạn cũng có thể làm

export default function(){} 
// or 
export default function*(){} 
// or 
export default class {} 

trong trường hợp này, chúng sẽ xuất khẩu các giá trị mà không ràng buộc sống vì họ không có tên.

Trong trường hợp cuối cùng là export default AssignmentExpression ;, đây là ví dụ của bạn về số export default a; thỏa mãn. Bạn có thể lưu ý rằng nó có [[LocalName]]: *default* thay vì [[LocalName]]: localName giống như những người khác. Đó là vì export default a; không nhận ra a là tên được xuất, nó xử lý nó như giá trị hiện tại của a là giá trị được xuất. Điều này không khác với export default 4;, nó không có tên từ quan điểm của thông số kỹ thuật.

Về cơ bản

export default function fn(){} 

tương đương với

function fn(){} 
export {fn as default}; 

nhưng

let a = 4; 
export default a; 

không tương đương với:

let a = 4; 
export {a as default}; 
+0

OK, 'let a = 4; mặc định xuất a' tương đương với 'xuất mặc định 4'. Có '[[LocalName]]: localName' /' [[LocalName]]: * mặc định * 'dẫn đến bất kỳ khác biệt về mặt thực tế nào (khi nhập, chế độ xem chỉ đọc trực tiếp, v.v.) không? – ftor

+0

Bạn nói đúng, thêm một ví dụ cho thấy lý do tại sao sự khác biệt đó lại quan trọng. – loganfsmyth

0

Như đã nêu trong:

Mozilla Docs

Kịch bản 1

Được sử dụng để xuất tên có tên

// module "my-module.js" 
export function cube(x) { 
    return x * x * x; 
} 
const foo = Math.PI + Math.SQRT2; 
export { cube, foo }; 

Kịch bản 2

Nó được sử dụng để xuất khẩu một giá trị duy nhất hoặc có giá trị dự phòng cho các mô-đun

// module "my-module.js" 
export default function cube(x) { 
    return x * x * x; 
} 

Không có đặc điểm kỹ thuật về sự khác biệt trong hoạt động mặc dù.

+2

Tôi không nghĩ rằng OP đang hỏi về cú pháp cho xuất khẩu có tên, nhưng thay vào đó là 'mặc định xuất X' so với' xuất {X làm mặc định}; '. – loganfsmyth

Các vấn đề liên quan