第 26 题:介绍模块化发展历程
可从IIFE、AMD、CMD、CommonJS、UMD、webpack(require.ensure)、ES Module、
<script type="module">这几个角度考虑。 【待了解】
第 27 题:全局作用域中,用 const 和 let 声明的变量不在 window 上,那到底在哪里?如何去获取?
【看不懂?】
const和let会生成块级作用域,可以理解为
let a = 10;
const b = 20;
//相当于:
(function(){
var a = 10;
var b = 20;
})()
ES5没有块级作用域的概念,只有函数作用域,可以近似理解成这样。所以外层window必然无法访问。
GlobalEnv是一个复合环境,包括一个由global构成的对象环境(objEnv)和一个一般声明的环境(declsEnv)组合而成,它是双环境组成的,统一交付一个环境存取的界面(objEnv/declsEnv 对应 Global/Script)。let/const 声明会放在declsEnv里面,而var的变量会通过ObjEnv来声明, 所以let,const 声明的变量不在window对象。 【待了解】
第 33 题:下面的代码打印什么内容,为什么?
var b = 10;
(function b(){
b = 20;
console.log(b);
})();
打印:
ƒ b(){
b = 20;
console.log(b);
}
因为在非匿名自执行函数中,函数变量为只读状态无法修改。【具体原因需要查IIFE在JS引擎的工作方式,堆栈存储IIFE的方式】
所以严格模式下会报错:Uncaught TypeError: Assignment to constant variable.
拓展:
有window:
var b = 10;
(function b() {
window.b = 20;
console.log(b); // [Function b]
console.log(window.b); // 20是必然的
})();
有var:
var b = 10;
(function b() {
var b = 20; // IIFE内部变量
console.log(b); // 20 【为什么不再是函数b了?因为函数b是window创建的?】
console.log(window.b); // 10
})();
第 34 题:简单改造下面的代码,使之分别打印 10 和 20。
var b = 10;
(function b(){
b = 20;
console.log(b);
})();
修改:
var b = 10;
(function b(){
var b = 20;
console.log(window.b);
console.log(b);
})();
或将window.b换成this.b。
第 41 题:下面代码输出什么
var a = 10;
(function () {
console.log(a)
a = 5
console.log(window.a)
var a = 20;
console.log(a)
})()
10 5 20 (错误)。
undefined 10 20 (正确)。
因为在立即执行函数中,var a = 20; 语句定义了一个局部变量 a,由于js的变量声明提升机制,局部变量a的声明会被提升至立即执行函数的函数体最上方,且由于这样的提升并不包括赋值,因此第一条打印语句会打印undefined,最后一条语句会打印20。
由于变量声明提升,a = 5; 这条语句执行时,局部的变量a已经声明,因此它产生的效果是对局部的变量a赋值,此时window.a 依旧是最开始赋值的10。
【为什么不是a = 5;最先变成全局变量?是因为有var的变量会首先提升?变量提升在引擎中是最先执行的吗?】