JavaScript/TypeScript不同导入方式的区别及使用问题咨询
以下是针对你提到的TS导入语法问题的解答,所有规则遵循ES Module(ESM)标准:
你给出的示例导入代码:
import * as THREE from 'three' import Stats from 'three/examples/jsm/libs/stats.module' import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls'
1 如何判断应该使用哪种导入方式?
导入方式完全由目标模块的导出规则决定,结合你有C#开发经验可以做简单类比:
- 目标模块用
export default做默认导出:用你熟悉的import XXX from '路径'的方式导入,对应你示例中的Stats导入,类似C#导入某个类的默认引用。 - 目标模块用
export单独导出多个成员:用import {XXX, YYY} from '路径'的命名导入方式,只导入你需要的特定成员。 - 你需要用到目标模块的所有导出内容:用
import * as XXX from '路径'的全量导入方式,将模块所有导出内容整合为一个对象使用,类似C#把整个命名空间的内容都挂载到一个自定义对象下访问。
2 导入语句中的*是什么作用?为什么第一行导入不需要写路径?
*是全量导入的标记,* as THREE的含义是:把three模块所有导出的成员(包括默认导出、所有命名导出)全部整合到名为THREE的对象中,后续你要使用three的内置能力都要通过THREE.成员名访问,比如创建场景要写new THREE.Scene()。- 第一行不需要写本地路径是因为
three是你通过npm/yarn等包管理工具安装的第三方依赖,TS/Node的模块解析器会自动去项目根目录的node_modules文件夹下查找对应包的入口文件,不需要你手写相对路径。只有导入你自己项目里的本地文件、或者第三方包内的非入口子文件(比如你示例中导入的OrbitControls属于three包的子路径内容)才需要写路径,逻辑和C#编译器自动查找系统程序集、不需要你写dll磁盘路径一致。
3 为什么OrbitControls需要放在大括号中导入?会进入全局空间吗?
- OrbitControls是
three/examples/jsm/controls/OrbitControls这个模块的命名导出成员,不是默认导出,所以必须用大括号匹配它的导出名称才能正确导入,相当于你从这个模块的所有导出内容里单独筛选出叫OrbitControls的成员拿出来用。如果这个模块没有默认导出,你不加{}直接导入的话会拿到undefined,无法实例化。 - 这种导入方式不会将OrbitControls加入全局空间,它只在当前你写导入语句的.ts文件的作用域内生效,所以你可以直接用
new OrbitControls(...)实例化,不需要加任何前缀,逻辑类似你C#中用using static导入了某个类之后可以直接使用。
内容的提问来源于stack exchange,提问作者Catlard
相关产品推荐
相关产品推荐

