使用带有javascript导入语法的方括号


115

我遇到了一个使用以下语法导入库的javascript库:

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

上面的方法和下面的方法有什么区别?

import React, Component, PropTypes from 'react';

4
答案在文档中
adeneo

4
从模块导入的成员用花括号括起来
adeneo


1
哈。如果我们消除所有的时间,可以用“ RTFM”回答一个SO问题,那么即使Jon Skeet的数字也可能少于6。; ^)
ruffin

Answers:


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

这说:

从名称下导入默认导出,并以相同的名称导入命名的导出。'react'ReactComponentPropTypes

这结合了您可能已经看到的两种常见语法

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";

OP的示例与

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

MDN文档继续显示示例

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

并声称这意味着

导入整个模块的内容,其中某些内容也被明确命名。这会将myModule(sic)foobar插入当前作用域。请注意,foomyModule.foo是相同的,因为是barmyModule.bar

MDN在此处所说的内容以及其他答案基于不正确的MDN文档所声称的观点绝对是错误的,并且可能基于规范的早期版本。这实际上是在做什么

导入默认模块导出和一些明确命名的导出。这会将MyModulefoobar插入当前范围。出口名称foobar不是通过访问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
Babel接受from '/path/to/my-module.js',尽管我个人使用from '/path/to/my-module'
royhowie

5
有了这样的详细说明,您还应该添加如何导出它们,以便像这样导入。
Caio Iglesias

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

这将从模块中获取导出的{ Component, PropTypes }成员,'react'并将它们分别分配给ComponentPropTypesReact将等于模块的default导出。

正如下面的torazaburo所指出的,这与

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

这是简写

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

这是另一个示例(链接到gist):

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

作为参考,您可以阅读importMDN 上的新文档。但是,显然需要技术审查。Axel Rauschmayer博士的博客文章目前是更好的参考。


1
这将从“反应”模块中的导出中获取{Component,PropTypes}属性,并将其分配给React。这是不正确的。它将默认导出分配给React,并将命名的导出ComponentPropTypes同名变量分配。不幸的是,MDN文档是错误的,您会发现是否尝试过。参见2ality.com/2014/09/es6-modules-final.html。同样,导入语法与解构分配绝对无关。

3
关于您对“新import文档”的评论,请查阅该MDN文章的修订历史记录,因为自该页面于一年多以前首次编写以来,您所引用的部分尚未修订,在此期间,模块语法已被修改。迅速改变。

1
@torazaburo我改写了我的答案,以便更加准确。
royhowie

@royhowie非常感谢这个例子!从字面上看,它节省了一个小时的时间,让您可以漫不经心地浏览……我只是有一个问题。在example3.js为什么它打印undefinedconsole.log(d)?既然您这样export default { a, b, d }做了,就可以将其导出到中myModule.js
CapturedTree

2
@ 1290 myModule.js,需要注意的是abc单独出口。这意味着另一个文件可以直接使用导入它们import { a } from 'myModule'。另一方面,d只能通过默认导出使用,因此另一个模块可以通过两种方式import thisObjectContainsDefault from 'myModule'访问它:并通过thisObjectContainsDefault.dOR import { default as wrapperObject }和进行访问wrapperObject.d。第二种方法的好处是,您还可以抓取单独导出的项目,如中所示example3.js
royhowie
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.