这是我参与2022首次更文挑战的第17天,活动详情查看:2022首次更文挑战
hi 我是小十七_,之前总结过一些 js 创建作用域的几种方式,分享给大家~
作用域的含义
当前的执行上下文,表示内部的变量是否可以被使用,将代码分层,子作用域可以访问父作用域中的变量,反之不行。
创建作用域的方式
for (var i=0; i<10; i++) { console.log( i );
// 尽管这样写,i 依然是全局变量
// 但是变量的声明离使用的地方越近越好
js 里面可以造成块作用域的方法
函数
用 with 关键字
try/catch 会创建块作用域,声明的变量只在catch内部有效
try{
undefined()
}catch(err){
console.log(err); // 能够正常执行
}
console.log(err); // Uncaught ReferenceError: err is not defined
let 可以将变量绑在所在的作用域中
可以用 { ... } 将 let 绑定在一个块作用域中.
var foo = 1;
if (foo) { // <-- 显式的块
let bar = foo * 2;
console.log( bar );
}
console.log( bar ); // ReferenceError
用 let 声明的变量不会发生变量的声明提升
console.log(aaa); // ReferenceError
let aaa = 111;
let 用于 for 循环中可以避免创建全局变量
for (let i=0; i<10; i++) {
console.log( i );
}
console.log( i ); // ReferenceError
const 创建块作用域
和 let 类似 const 也可以创建块作用域,不同的是, const 声明的变量值不允许改变。
{
const b = 3;
b = 4; // Assignment to constant variable
}
console.log(b); // ReferenceError
对于非基础类型(对象),比较的是引用是否变化。如果给对象加一个键值是可以的,但是对象引用的地址不能变化。
模块相关
解决的问题
在 es6 之前,js 中没有模块体系,不能把一个大程序拆分为一个个小文件。(写一个复杂的项目,单个js文件和其他文件没有显式的联系) 社区使用 CommonJS 和 AMD 作为模块的加载方案(require),但是这种只能在运行时确定依赖关系,不能单独加载模块中的单个对象,只能加载整个模块
// CommonJS模块
let { stat, exists, readFile } = require('fs');
// 等同于
let _fs = require('fs');
let stat = _fs.stat;
let exists = _fs.exists;
let readfile = _fs.readfile;
es6 中的 export 和 import 是在编译时加载,可以对模块进行静态分析,可以选择性加载需要的函数
// ES6模块
import { stat, exists, readFile } from 'fs';
import 和 export
模块由 import 和 export 两个关键字构成,一个模块就是一个独立的文件,模块 export 的可以是 class,变量,函数等。模块内部采取严格模式。 可以用 export default 导出整个模块,一个文件只能使用一次,不需要关注模块内函数的名字
// 第一组
export default function crc32() { // 输出
// ...
}
import crc32 from 'crc32'; // 输入
// 第二组
export function crc32() { // 输出
// ...
};
import {crc32} from 'crc32'; // 输入
import * as enum from './enum.js' 可以引入 export 和 export default 导出的内容
import enum from './enum.js' 可以引入 export default 导出的内容
import {enum} from './enum.js' 可以引入 export 导出的内容