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

Posted

技术标签:

【中文标题】使用带有 javascript 导入语法的括号【英文标题】:using brackets with javascript import syntax 【发布时间】:2015-09-14 18:57:33 【问题描述】:

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

import React,  Component, PropTypes  from 'react';

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

import React, Component, PropTypes from 'react';

【问题讨论】:

答案在documentation 从模块中导入的成员用大括号括起来 另见Javascript (ES6), export const vs export default 哈。如果我们排除所有可以用“RTFM”回答 SO 问题的时间,即使 Jon Skeet 也可能少于六位数。 ;^) 【参考方案1】:
import React,  Component, PropTypes  from 'react';

这说:

'react' 导入名为React默认 导出,并以相同的名称导入命名 导出ComponentPropTypes。 p>

这结合了您可能见过的两种常见语法

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(原文如此)、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';

【讨论】:

Babel 接受from '/path/to/my-module.js',虽然我个人使用from '/path/to/my-module' 有了这么详细的解释,您还应该添加它们是如何导出的,以便像那样导入。【参考方案2】:
import React,  Component, PropTypes  from 'react'

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

As noted by torazaburo below,这个是一样的

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

这是的简写

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

这是另一个示例 (link to 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 | 

作为参考,您可以阅读来自 MDN 的新 import 文档。然而,它显然需要技术审查。 Dr. Axel Rauschmayer's blog post 现在是更好的参考。

【讨论】:

这将从“react”模块中的导出中获取 Component, PropTypes 属性并将它们分配给 React。 这是不正确的。它将默认导出分配给React,并将命名导出ComponentPropTypes 分配给同名变量。不幸的是,MDN 文档是错误的,如果您尝试过就会发现。见2ality.com/2014/09/es6-modules-final.html。此外,导入语法与解构赋值完全无关。 关于您对“新的import 文档”的评论,查看该 MDN 文章的修订历史,您引用的部分自从该页面首次编写超过一年前,模块语法迅速变化的时期。 @torazaburo 我重写了我的答案以更准确。 @royhowie 非常感谢这个例子!从字面上节省了另一个小时的无意识浏览......我只有一个问题。在example3.js 中,为什么会为console.log(d) 打印undefined?既然你做了export default a, b, d ,所以你确实将它导出到myModule.js @1290 在myModule.js 中,请注意abc 是单独导出的。这意味着另一个文件可以直接使用import a from 'myModule' 导入它们。另一方面,d 只能通过默认导出获得,因此另一个模块可以通过两种方式访问​​它:import thisObjectContainsDefault from 'myModule' 和通过thisObjectContainsDefault.dimport default as wrapperObject wrapperObject.d 访问它。第二种方法的好处是您还可以抓取单独导出的项目,如example3.js 所示。

以上是关于使用带有 javascript 导入语法的括号的主要内容,如果未能解决你的问题,请参考以下文章

javascript点语法与中括号语法

MyEcplise导入项目报错:Errors running builder 'JavaScript Validator' on project '项目名'. ja

javascript入门资料资源搜集

如何使用JavaScript从浏览器打印图像

JavaScript函数对象和数组

为啥在带有括号的 Javascript 事件处理函数中?