1,IIFE的函数无法进行赋值
var foo = 10;
(function foo() {
console.log(foo); // [function foo]
// 内部作用域,会先去查找是已有变量foo的声明,有就直接赋值20,确实有了呀,发现了具名函数,拿此foo做赋值
// IIFE的函数无法进行赋值(内部机制,类似const定义的常量)所以无效
foo = 20;
console.log(foo); // [function foo]
console.log(window.foo)//10
})()
所以严格模式下能看到错误:
// 所以严格模式下能看到错误:uncaught typeerror: assignment to constant variable
var foo = 10;
(function foo() {
'use strict'
console.log(foo);
foo = 20; // uncauth typerror: assignment to constant variable
console.log(foo);
console.log(window.foo)
})()
2,
//在全局作用域中声明 `b`,并挂载到 `window` 对象上。
var b = 10;
(
function b() {
//`window.b = 20` 修改的是全局对象的 `b`,即覆盖了全局作用域中 `var b = 10` 的值
window.b = 20;
//在 IIFE 作用域中,`b` 指向的是IIFE 定义的具名函数。
//在 IIFE 内部,`b` 是指向函数本身的**局部变量**,优先级高于全局作用域。
console.log(b); //【function b】
console.log(window.b) // 20;
}
)()
3,IIFE声明了一个新的局部变量,可以与函数同名,局部变量可以遮蔽外部的全局变量
// 使用 `var` 在全局作用域中声明了变量 `b`,
//`var` 声明的变量会自动挂载到 `window` 对象上:
var b = 10;
(function b() {
// 由于是具名函数,IIFE 内部的 `b` 会指向这个函数自身(在函数体内是只读的)。
// 但在函数体内,声明了一个新的局部变量 `b`,这个新的 `b` 会遮蔽外部的`b`
var b = 20;
console.log(b); // 20
//IIFE 内部的变量声明**不会影响全局作用域的变量**。
console.log(window.b); // 10
})();
4,var a 在函数内被提升,但未赋值,默认为 undefined。
var a = 10;
(function () {
// `var a = 20` 会在编译阶段被提升到作用域的顶部,变量声明提升,但未赋值,默认为 undefined 等于多了一行代码:var a; 然后 倒数第二行 被改成 a=20
console.log(a) // undefined
// a被赋值5
a = 5;
console.log(a) // 5
console.log(window.a) // 10
//局部作用域中的 `a` 被赋值为 `20`。
var a = 20;
console.log(a) //20
})()
5,
-
如果 IIFE 内部没有声明局部变量
a,JavaScript 就会通过作用域链去全局作用域寻找a。 -
由于全局作用域存在
var a = 10,所以 IIFE 直接使用全局的a。 -
a = 5就会直接修改全局a的值。
//如果把 var a = 20,这段去掉,那么就只能去拿外部a的值了
var a = 10;
(function () {
console.log(a) // 10
a = 5
console.log(a) // 5
//因为 `a = 5` 修改了全局的 `a`,所以 `window.a` 现在是 `5`。
console.log(window.a) // 5
})()