Javascript模块化开发基础,最新美团点评前端团队面试题

简介: Javascript模块化开发基础,最新美团点评前端团队面试题
export {a, b, c}
//main.js
import {a, b, c} from ‘./abc’; //接受的变量用大括号表示,以解构赋值的形式获取
console.log(a, b, c);
导入的时候也可以为变量重新取一个名字
import {a as aa, b, c};
console.log(aa, b, c)
如果想在一个模块中先输入后输出同一个模块,import语句可以和export语句写在一起。
// 正常写法
import {a, b, c} form ‘./abc’;
export {a, b, c}
// 使用简写, 可读性不好,不建议
export {a, b, c} from ‘./abc’;
//ES7 提议,在简化先输入后输出的写法。现在不能使用,也不建议使用,可读性不好
export a, b, c from ‘./abc’

使用 import 和 export 需要注意一下几个方面:

  • export 必须写在所在模块作用于的顶层。如果写在了内部作用于会报错
  • export 输出的值是动态绑定的,绑定在其所在的模块。
// foo.js
export var foo = ‘foo’;
setTimeout(function() {
foo = ‘foo2’;
}, 500);
// main.js
import * as m from ‘./foo’;
console.log(m.foo); // foo

setTimeout(() => console.log(m.foo), 500); //foo2 500ms 后同样会被修改

  • import 具有声明提升,而且会提升到整个文件最上面
  • import 获得的变量都是只读的,修改它们会报错
  • 在 export 输出内容时,如果同时输出多个变量,需要使用大括号{},同时 import 导入多个变量也需要大括号
  • import 引入模块的默认后缀是 .js, 所以写的时候可以忽略 js 文件扩展名
  • import 会执行要所加载的模块。如下写法仅仅执行一个模块,不引入任何值

import ‘./foo’; //执行 foo.js 但不引入任何值

模块整体加载

当然模块可以作为整体加载,使用*关键字,并利用 as 重命名得到一个对象,所有获得的 export 的函数、值和类都是该对象的方法:

// abc.js
export var a = 1;
export var b = 2;
export var c = 3;
// main.js
import * as abc from ‘./abc’;
console.log(abc.a, abc.b, abc.c);
上面 main.js 中的整体加载可以用 module 关键字实现:
//暂时无法实现
module abc from ‘./abc’;
console.log(abc.a, abc.b, abc.c); //1 2 3

注意,以上2种方式获得的接口,不包括 export default 定义的默认接口。

export default

为了使模块的用户可以不看文档,或者少看文档,输出模块的时候利用 export default 指定默认输出的接口。使用 export defalut 输出时,不需要大括号,而 import 输入变量时,也不需要大括号(没有大括号即表示获得默认输出)

// abc.js
var a = 1, b = 2, c = 3;
export {a, b};
export default c; //等价于 export default 3;
// main.js
import {a, b} from ‘./abc’;
import num from ‘./abc’; // 不需要大括号, 而且可以直接改名(如果必须用原名不还得看手册么?)
console.log(a, b, num) // 1 2 3

本质上,export default输出的是一个叫做default的变量或方法,输入这个default变量时不需要大括号。

// abc.js
var a = 20;
export {a as default};
// main.js
import a from ‘./abc’; // 这样也是可以的
console.log(a); // 20
// 这样也是可以的
import {default as aa} from ‘./abc’;
console.log(aa); // 20
如果需要同时输入默认方法和其他变量可以这样写 import:
import customNameAsDefaultExport, {otherMethod}, from ‘./export-default’;

这里需要注意:一个模块只能有一个默认输出,所以 export default 只能用一次

模块的继承

所谓模块的继承,就是一个模块 B 输出了模块 A 全部的接口,就仿佛是 B 继承了 A。利用 export * 实现:

// circleplus.js
export * from ‘circle’; //当然,这里也可以选择只继承其部分接口,甚至可以对接口改名
export var e = 2.71828182846;
export default function(x){ //重新定义了默认输出,如果不想重新定义可以:export customNameAsDefaultExport from ‘circle’;
return Math.exp(x);
}
//main.js
import * from ‘circleplus’; //加载全部接口
import exp from ‘circleplus’; //加载默认接口
//…use module here

上面这个例子 circleplus 继承了 circle。值得一提的是,export * 不会再次输出 circle 中的默认输出(export default)。

在使用和定义模块时,希望可以做到以下几个建议:

  • Module 语法是 JavaScript 模块的标准写法,坚持使用这种写法。使用 import 取代 require, 使用 export 取代module.exports
  • 如果模块只有一个输出值,就使用 export default,如果模块有多个输出值,就不使用 export default
  • 尽量不要 export default 与普通的 export 同时使用
  • 不要在模块输入中使用通配符。因为这样可以确保你的模块之中,有一个默认输出(export default)
  • 如果模块默认输出一个函数,函数名的首字母应该小写;如果模块默认输出一个对象,对象名的首字母应该大写

ES6 模块加载的实质

ES6 模块加载的机制是值的应用,而 CommonJS 是值的拷贝。这意味着, ES6 模块内的值的变换会影响模块外对应的值,而 CommonJS 不会。 ES6 遇到 import 时不会立刻执行这个模块,只生成一个动态引用,需要用的时候再去里面找值。有点像 Unix 中的符号链接。所以说 ES6的模块是动态引用,不会缓存值。之前的这个例子就可以说明问题:

// foo.js
export let counter = 3;
export function inc(){
counter++;
}
// main.js
import {counter, inc} from ‘./foo’;
console.log(counter); //3
inc();
console.log(counter); //4
我们看一个 CommonJS 的情况
// foo.js
let counter = 3;
function inc(){
counter++;
}
module.exports = {
counter: counter,
inc: inc
}
相关文章
|
JSON 自然语言处理 前端开发
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
641 72
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
|
11月前
|
JavaScript 前端开发 API
|
11月前
|
前端开发 JavaScript 数据可视化
58K star!这个让网页动起来的JS库,前端工程师直呼真香!
Anime.js 是一款轻量级但功能强大的JavaScript动画引擎,它能够以最简单的方式为网页元素添加令人惊艳的动效。这个项目在GitHub上已经获得58,000+星标,被广泛应用于电商页面、数据可视化、游戏开发等场景。
418 8
|
自然语言处理 JavaScript 前端开发
当面试官再问我JS闭包时,我能答出来的都在这里了。
闭包(Closure)是前端面试中的高频考点,广泛应用于函数式编程中。它不仅指函数内部定义的函数,还涉及内存管理、作用域链和垃圾回收机制。闭包可以让函数访问其外部作用域的变量,但也可能引发内存泄漏等问题。通过合理使用闭包,可以实现模块化、高阶函数和回调函数等应用场景。然而,滥用闭包可能导致代码复杂度增加、调试困难以及潜在的性能问题。为了避免这些问题,开发时应谨慎处理闭包,避免不必要的嵌套,并及时清理不再使用的变量和监听器。
519 16
当面试官再问我JS闭包时,我能答出来的都在这里了。
|
12月前
|
资源调度 JavaScript 前端开发
前端开发必备!Node.js 18.x LTS保姆级安装教程(附国内镜像源配置)
本文详细介绍了Node.js的安装与配置流程,涵盖环境准备、版本选择(推荐LTS版v18.x)、安装步骤(路径设置、组件选择)、环境验证(命令测试、镜像加速)及常见问题解决方法。同时推荐开发工具链,如VS Code、Yarn等,并提供常用全局包安装指南,帮助开发者快速搭建高效稳定的JavaScript开发环境。内容基于官方正版软件,确保合规性与安全性。
11881 23
|
前端开发
【2025优雅草开源计划进行中01】-针对web前端开发初学者使用-优雅草科技官网-纯静态页面html+css+JavaScript可直接下载使用-开源-首页为优雅草吴银满工程师原创-优雅草卓伊凡发布
【2025优雅草开源计划进行中01】-针对web前端开发初学者使用-优雅草科技官网-纯静态页面html+css+JavaScript可直接下载使用-开源-首页为优雅草吴银满工程师原创-优雅草卓伊凡发布
378 1
【2025优雅草开源计划进行中01】-针对web前端开发初学者使用-优雅草科技官网-纯静态页面html+css+JavaScript可直接下载使用-开源-首页为优雅草吴银满工程师原创-优雅草卓伊凡发布
|
JavaScript 前端开发 Java
springboot解决js前端跨域问题,javascript跨域问题解决
本文介绍了如何在Spring Boot项目中编写Filter过滤器以处理跨域问题,并通过一个示例展示了使用JavaScript进行跨域请求的方法。首先,在Spring Boot应用中添加一个实现了`Filter`接口的类,设置响应头允许所有来源的跨域请求。接着,通过一个简单的HTML页面和jQuery发送AJAX请求到指定URL,验证跨域请求是否成功。文中还提供了请求成功的响应数据样例及请求效果截图。
293 3
springboot解决js前端跨域问题,javascript跨域问题解决
|
缓存 前端开发 JavaScript
JavaScript前端路由的实现原理及其在单页应用中的重要性,涵盖前端路由概念、基本原理、常见实现方式
本文深入解析了JavaScript前端路由的实现原理及其在单页应用中的重要性,涵盖前端路由概念、基本原理、常见实现方式(Hash路由和History路由)、优点及挑战,并通过实际案例分析,帮助开发者更好地理解和应用这一关键技术,提升用户体验。
621 1
|
存储 人工智能 前端开发
前端大模型应用笔记(三):Vue3+Antdv+transformers+本地模型实现浏览器端侧增强搜索
本文介绍了一个纯前端实现的增强列表搜索应用,通过使用Transformer模型,实现了更智能的搜索功能,如使用“番茄”可以搜索到“西红柿”。项目基于Vue3和Ant Design Vue,使用了Xenova的bge-base-zh-v1.5模型。文章详细介绍了从环境搭建、数据准备到具体实现的全过程,并展示了实际效果和待改进点。
1320 14
|
JavaScript 前端开发 程序员
前端学习笔记——node.js
前端学习笔记——node.js
583 0

热门文章

最新文章