-
脚本和模块的区别
脚本:
由浏览器或者node环境引入执行的脚本具有主动性的JavaScript代码段 控制宿主完成一定任务的代码 引入: <script src='...js'></script> 包含: js语句
模块:
只能由JavaScript代码用import引入执行的被动性的JavaScript代码段 等待被调用的库 直接import 只是保证了这个模块代码被执行 引入它的模块是无法获得它的任何信息 引入: export default{} import '' from '' // 把模块默认的导出值放入变量v import '' // 引入一个模块 <script type='module' src='...js'></script> 带from 的 import 是引入模块中的一部分信息 可以把它们变成本地变量 有三种用法: import x from "./a.js"; // 引入模块中导出的默认值 import d, {a as x, modify} from "./a.js" import d, * as x from "./a.js" import {a as x, modify} from "./a.js"; // 引入模块中的变量 import * as x from "./a.js"; //把模块中所有的变量以类似对象属性的方式引入 包含: import export 语句 export 声明: a. 独立使用export声明 export {a, b, c} b. 直接在声明型语句前添加export关键字 var function (含 async 和 generator) class let const c. export default 可以使用 import x from "./a.js" //这样的引入 var a = {}; export default a;
-
函数体
跟脚本和模块比起来 函数体中的语句列表多了return语句可以使用普通函数体 异步函数体 生成器函数体 异步生成器函数体
-
函数体、模块和脚本能使用的语句
类型 yield await return import&export
普通函数体 x x √ x
异步函数体 x √ √ x
生成器函数体 √ x √ x
异步生成器函数体 √ √ √ x
脚本 x x x x
模块 x x x √ -
预处理
var声明 ( 永远作用于脚本、模块和函数体这个级别 )
var 的作用能够穿透一切语句结构 它只认脚本、模块、函数体三种语法结构
var a = 1; function foo(){ var o = {a:3}; with(o){ var a = 2; } console.log(o.a); // 2 console.log(a); // undefined }
在执行阶段,当执行到var a = 2时,作用域变成了 with 语句内,这时候的 a 被认为访问到了对象 o 的属性 a,所以最终执行的结果,我们得到了 2 和 undefined。
// 利用了IIFE的独立作用域 使得作用域独立
for(var i = 0; i < 20; i ++) {
void function(i){
var div = document.createElement(“div”);
div.innerHTML = i;
div.onclick = function(){
console.log(i);
}
document.body.appendChild(div);
}(i);
}
// 没有使用IIFE 最后得出的序号一致
for(var i = 0; i < 20; i ++) {
var div = document.createElement(“div”);
div.innerHTML = i;
div.onclick = function(){
console.log(i);
}
document.body.appendChild(div);
}
-
function声明
function 声明表现跟 var 相似,不同之处在于,function 声明不但在作用域中加入变量,还会给它赋值
console.log(foo); function foo(){ }
-
class 声明
class 的声明作用不会穿透if等语句结构 所以只有在全局环境才会有声明作用
class 声明也是会被预处理的,它会在作用域中创建变量,并且要求访问它时抛出错误。console.log©;
class c{}
// 会报错var c = 1;
function foo(){
console.log©;
class c {}
}
foo();// 会报错
-
指令序言机制
它只能出现在脚本、模块和函数体的最前面