використовуючи дужки з синтаксисом імпорту javascript


115

Я натрапив на бібліотеку javascript, яка використовує такий синтаксис для імпорту бібліотек:

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

Яка різниця між вищезазначеним методом та наступним?

import React, Component, PropTypes from 'react';

4
Відповідь - у документації
adeneo

4
Учасники для імпорту з модуля укладені у фігурні фігури
adeneo


1
Ха. Якби ми усунули весь час, можна було б, безперечно, відповісти на запитання "RTFM", навіть Джон Скіт може мати менше шести фігур. ; ^)
ruffin

Відповіді:


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

Це говорить:

Імпортуйте експорт за замовчуванням з- 'react'під імені Reactта імпортуйте названий експорт Componentта PropTypesпід тими ж назвами.

Це поєднує в собі два поширених синтаксису, які ви, напевно, бачили

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

Перший використовується для імпорту та назви експорту за замовчуванням, другий для імпорту вказаного експорту.

За загальним правилом, більшість модулів надаватимуть єдиний експорт за замовчуванням або список названих експортерів. Дещо менш звичним для модуля є надання як експорту за замовчуванням, так і названого експорту. Однак у випадку, коли є одна особливість, яка найчастіше імпортується, а також додаткові підфункції, це дійсна конструкція для експорту першої як за замовчуванням, а решти як названої експорту. Саме в таких випадках ви використовуєте importсинтаксис, на який ви посилаєтесь.

Інші відповіді десь між помилковими та заплутаними, можливо, тому, що документи MDN під час запитання цього питання були помилковими та заплутаними. MDN показав приклад

import name from "module-name";

і nameце "ім'я об'єкта, який отримає імпортовані значення". Але це вводить в оману і неправильно; Перш за все, існує лише одне значення імпорту, яке буде "отримано" (чому б не сказати просто "призначено" або "використовується для посилання") name, а значення імпорту в цьому випадку - експорт за замовчуванням з модуля .

Ще один спосіб пояснення цього - зазначити, що вищевказаний імпорт точно ідентичний

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

і приклад ОП точно ідентичний

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

Документація MDN продовжувала показувати приклад

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

і стверджував, що це означає

Імпортуйте вміст цілого модуля, а деякі також мають чітке ім'я. Це вставляє myModule(sic) foo, і barв поточну область. Зауважте, що fooі myModule.fooтакі самі, як barіmyModule.bar

Що тут говорив MDN та які відповіді на інші відповіді, виходячи з неправильної документації MDN, абсолютно невірно і може базуватися на більш ранній версії специфікації. Насправді це і є

Імпортуйте експорт модуля за замовчуванням та деякий експліцитно названий експорт. Це вставляє MyModule, fooі barв поточну область. Імена експорту fooі barє НЕ доступні черезMyModule , який є по замовчуванням експорту, а не якийсь - то парасолька охоплює весь експорт.

(Експорт модуля за замовчуванням - це значення, експортоване із export defaultсинтаксисом, яке також може бути export {foo as default}.)

Автори документації MDN, можливо, заплуталися у такій формі:

import * as MyModule from 'my-module';

Це імпортує весь експорт з my-moduleта робить їх доступними під такими назвами, як MyModule.name. Експорт за замовчуванням також доступний як MyModule.default, оскільки експорт за замовчуванням насправді є не що інше, як інший імпорт з ім'ям default. У цьому синтаксисі немає способу імпортувати лише підмножину названого експорту, хоча можна імпортувати експорт за замовчуванням, якщо він є, разом із усім названим експортом, з

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

1
Вавилон приймає from '/path/to/my-module.js', хоча я особисто користуюся from '/path/to/my-module'.
royhowie

5
Маючи таке детальне пояснення, ви також повинні додати спосіб їх експорту, щоб імпортуватись таким чином.
Кайо Іглесіас

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

Це буде захоплювати експортовані { Component, PropTypes }елементи з 'react'модуля і привласнити їх Componentі PropTypes, відповідно. Reactбуде дорівнює defaultекспорту модуля .

Як зазначає торазабуро нижче , це те саме, що

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

який є скороченим

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

Ось ще один приклад ( посилання на суть ):

// 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...'

Я тестував другий приклад з babel:

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

і отримала синтаксичну помилку.

~/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 | 

Для довідки ви можете прочитати нову importдокументацію з MDN. Однак, очевидно, потрібен технічний огляд. Повідомлення в блозі доктора Акселя Раушмаєра є кращою орієнтацією на даний момент.


1
Це захопить властивості {Component, PropTypes} з експорту в модуль 'react' та призначить їх React. Це неправильно. Він призначає експорт за замовчуванням до React, а також названий експорт Componentта PropTypesоднойменні змінні. На жаль, документи MDN помиляються, як ви дізнаєтесь, якби ви спробували це. Дивіться 2ality.com/2014/09/es6-modules-final.html . Крім того, синтаксис імпорту не має абсолютно нічого спільного з присвоєнням руйнування.

3
Що стосується Вашого коментаря до "нової importдокументації", переглядаючи історію редакції цієї статті MDN, частини, які ви цитуєте, не були переглянуті, оскільки сторінка була вперше написана більше року тому, період, протягом якого синтаксис модуля був швидко змінюється.

1
@torazaburo Я переписав свою відповідь, щоб бути більш точним.
royhowie

@royhowie Дякую вам за цей приклад !! Буквально заощаджено ще одну годину, яку варто бездумно переглядати ... У мене просто одне питання. В example3.jsчому це надрукувати undefinedдля console.log(d)? Так як ви це зробили, export default { a, b, d }ви експортували його в myModule.js.
Захоплене

2
@ 1290 В myModule.js, зауважте, щоa , bі cбули вивезені в індивідуальному порядку . Це означає, що інший файл може імпортувати їх безпосередньо import { a } from 'myModule'. З іншого боку, dдоступний лише через експорт за замовчуванням, тому інший модуль може отримати доступ до нього двома способами: import thisObjectContainsDefault from 'myModule'та отримати доступ через нього thisObjectContainsDefault.dАБО import { default as wrapperObject }та wrapperObject.d. Перевага другого підходу полягає в тому, що ви також можете захопити предмети, які були експортовані індивідуально, як це видно в example3.js.
royhowie
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.