sử dụng dấu ngoặc với cú pháp nhập javascript


115

Tôi đã xem qua một thư viện javascript sử dụng cú pháp sau để nhập các thư viện:

import React, { Component, PropTypes } from 'react';

Sự khác biệt giữa phương pháp trên và phương pháp sau đây là gì?

import React, Component, PropTypes from 'react';

4
Câu trả lời có trong tài liệu
adeneo

4
Các thành viên cần nhập từ mô-đun được đặt trong dấu ngoặc kép
adeneo


1
Ha. Nếu chúng tôi loại bỏ tất cả những lần người ta có thể trả lời một câu hỏi SO bằng "RTFM", thì ngay cả Jon Skeet cũng có thể có ít hơn sáu con số. ; ^)
ruffin

Câu trả lời:


174
import React, { Component, PropTypes } from 'react';

Điều này nói:

Nhập tệp xuất mặc định từ'react' dưới tên Reactvà nhập các bản xuất được đặt tênComponentPropTypesdưới cùng tên.

Điều này kết hợp hai cú pháp phổ biến mà bạn có thể đã thấy

import React from 'react';
import { Component, PropTypes } from 'react';

Đầu tiên được sử dụng để nhập và đặt tên cho xuất mặc định, thứ hai để nhập các xuất được đặt tên đã chỉ định.

Theo nguyên tắc chung, hầu hết các mô-đun sẽ cung cấp một bản xuất mặc định, hoặc một danh sách các bản xuất được đặt tên. Một mô-đun có thể cung cấp cả một bản xuất mặc định thì hơi ít bình thường hơn được đặt tên . Tuy nhiên, trong trường hợp có một đối tượng địa lý được nhập phổ biến nhất, nhưng cũng có các tính năng phụ bổ sung, thì đó là thiết kế hợp lệ để xuất tính năng đầu tiên làm mặc định và các tính năng còn lại được đặt tên là xuất khẩu. Trong những trường hợp như vậy, bạn sẽ sử dụng importcú pháp mà bạn tham khảo.

Các câu trả lời khác nằm ở đâu đó giữa sai và khó hiểu, có thể vì các tài liệu MDN tại thời điểm câu hỏi này được hỏi là sai và khó hiểu. MDN đưa ra ví dụ

import name from "module-name";

và được cho namelà "tên của đối tượng sẽ nhận các giá trị đã nhập." Nhưng điều đó gây hiểu lầm và không chính xác; trước hết, chỉ có một giá trị nhập, giá trị này sẽ được "nhận" (tại sao không chỉ nói "được gán cho" hoặc "được sử dụng để tham chiếu đến")name và giá trị nhập trong trường hợp này là xuất mặc định từ mô-đun .

Một cách khác để giải thích điều này là lưu ý rằng việc nhập khẩu ở trên hoàn toàn giống với

import { default as name } from "module-name";

và ví dụ của OP hoàn toàn giống với

import { default as React, Component, PropTypes } from 'react';

Tài liệu MDN tiếp tục cho thấy ví dụ

import MyModule, {foo, bar} from "my-module.js";

và tuyên bố rằng nó có nghĩa là

Nhập toàn bộ nội dung của mô-đun, với một số cũng được đặt tên rõ ràng. Điều này chèn myModule(sic) foo, và barvào phạm vi hiện tại. Lưu ý rằng foomyModule.foogiống nhau, như là barmyModule.bar

Những gì MDN nói ở đây và những câu trả lời khác khẳng định dựa trên tài liệu MDN không chính xác, là hoàn toàn sai và có thể dựa trên phiên bản trước của thông số kỹ thuật. Điều này thực sự làm là

Nhập xuất mô-đun mặc định và một số xuất khẩu được đặt tên rõ ràng. Chèn này MyModule, foobarvào phạm vi hiện tại. Tên xuất khẩu foobarkhông thể truy cập quaMyModule , đó là mặc định xuất khẩu, không phải một số ô bao gồm tất cả xuất khẩu.

(Xuất mô-đun mặc định là giá trị được xuất với export defaultcú pháp, cũng có thể là export {foo as default}.)

Người viết tài liệu MDN có thể đã nhầm lẫn với biểu mẫu sau:

import * as MyModule from 'my-module';

Nhập khẩu này, tất cả xuất khẩu từ my-module, và làm cho họ tiếp cận dưới những cái tên như MyModule.name. Xuất mặc định cũng có thể truy cập được MyModule.defaultvì xuất mặc định thực sự không hơn gì một xuất có tên khác có tên default. Trong cú pháp này, không có cách nào để chỉ nhập một tập hợp con của các xuất đã đặt tên, mặc dù người ta có thể nhập xuất mặc định, nếu có, cùng với tất cả các xuất được đặt tên, với

import myModuleDefault, * as myModule from 'my-module';

1
Babel chấp nhận from '/path/to/my-module.js', mặc dù cá nhân tôi sử dụng from '/path/to/my-module'.
royhowie

5
Với giải thích chi tiết như vậy, bạn cũng nên thêm cách chúng được xuất để được nhập như vậy.
Caio Iglesias,

37
import React, { Component, PropTypes } from 'react'

Thao tác này sẽ lấy các { Component, PropTypes }thành viên đã xuất từ 'react'mô-đun và gán chúng cho ComponentPropTypestương ứng. Reactsẽ bằng với defaultxuất của mô-đun .

Theo ghi nhận của torazaburo dưới đây , điều này giống như

import { default as React, Component, PropTypes } from 'react'

đó là viết tắt của

import { default as React, Component as Component, PropTypes as PropTypes} from 'react'

Đây là một ví dụ khác ( liên kết đến ý chính ):

// myModule.js
export let a = true
export let b = 42
export let c = 'hello, world!'
// `d` is not exported alone
let d = 'some property only available from default'

// this uses the new object literal notation in es6
// {myVar} expands to { myVar : myVar }, provided myVar exists
// e.g., let test = 22; let o = {test}; `o` is then equal to { test : 22 }
export default { a, b, d }

// example1.js
import something from 'myModule'
console.log(something)
// this yields (note how `c` is not here):
/*
  {
    a : true,
    b : 42,
    d : 'some property only available from default'
  }
*/

// example2.js
import something, { c } from 'myModule'
console.log(something)  // same as above; the `default` export
console.log(c)          // c === 'hello, world!'

// example3.js
import { a, b, d, default as something } from 'myModule'
console.log(a)            // a === true
console.log(b)            // b === 42
console.log(d)            // d === undefined (we didn't export it individually)
console.log(something.d)  // something.d === 'some property...'

Tôi đã thử nghiệm ví dụ thứ hai với babel:

import test, test3, test2 from './app/lib/queries.js'
console.log(test, test3, test2)

và có lỗi cú pháp.

~/code/repo/tutoring $ babel-node test.js
/Users/royhowie/.node/lib/node_modules/babel/node_modules/babel-core/lib/babel/transformation/file/index.js:601
      throw err;
            ^
SyntaxError: /Users/royhowie/code/repo/tutoring/test.js: Unexpected token (1:13)
> 1 | import test, test3, test2 from './app/lib/queries.js'
    |              ^
  2 | 
  3 | console.log(test, test3, test2)
  4 | 

Để tham khảo, bạn có thể đọc importtài liệu mới từ MDN. Tuy nhiên, rõ ràng nó đang cần được xem xét kỹ thuật. Bài đăng trên blog của Tiến sĩ Axel Rauschmayer là một tài liệu tham khảo tốt hơn cho bây giờ.


1
Thao tác này sẽ lấy các thuộc tính {Component, PropTypes} từ các lần xuất trong mô-đun 'react' và gán chúng cho React. Điều này là không đúng. Nó chỉ định xuất mặc định cho React, và xuất có tên ComponentPropTypescho các biến có cùng tên. Thật không may, tài liệu MDN không chính xác, bạn sẽ tìm hiểu nếu bạn đã thử. Xem 2ality.com/2014/09/es6-modules-final.html . Ngoài ra, cú pháp nhập hoàn toàn không liên quan gì đến việc gán hàm hủy.

3
Đối với nhận xét của bạn về " importtài liệu mới`, xem lại lịch sử sửa đổi của bài báo MDN đó, các phần bạn đang trích dẫn chưa được sửa đổi kể từ khi trang này được viết lần đầu tiên hơn một năm trước, khoảng thời gian mà cú pháp mô-đun là thay đổi nhanh chóng.

1
@torazaburo Tôi đã viết lại câu trả lời của mình để chính xác hơn.
royhowie

@royhowie Cảm ơn bạn rất nhiều về ví dụ này !! Theo nghĩa đen, đã tiết kiệm được một giờ đáng để lướt qua xung quanh ... Tôi chỉ có một câu hỏi. Trong example3.jstại sao nó in undefinedcho console.log(d)? Vì bạn đã làm export default { a, b, d }như vậy nên bạn đã xuất nó vào myModule.js.
CapturedTree

2
@ 1290 Trong myModule.js, lưu ý rằng a, bcđã được xuất khẩu cá nhân. Điều này có nghĩa là một tệp khác có thể nhập chúng trực tiếp với import { a } from 'myModule'. Mặt khác, dchỉ có sẵn thông qua xuất mặc định, do đó, một mô-đun khác có thể truy cập nó theo hai cách: import thisObjectContainsDefault from 'myModule'và truy cập nó qua thisObjectContainsDefault.dOR import { default as wrapperObject }wrapperObject.d. Lợi ích của cách tiếp cận thứ hai là bạn cũng có thể lấy các mục được xuất riêng lẻ, như có thể thấy trong example3.js.
royhowie
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.