第二章 深入变量和闭包
2.1 加var和不加var的变量的区别
- var的变量有提升
- 不管有没有加var,创建的全局变量都会在GO里面
- 加var的变量可能是全局变量,也可能是局部变量;不加var的变量只能是全局变量。
2.2 let变量的特点
-
let声明有提升,单没有初始化。
-
let配合{},有块级作用域
在全局作用域中,用 let 和 const 声明的全局变量并没有在全局对象中,只是一个块级作用域(Script)中。那要怎么获取呢?在定义变量的块级作用域中就能获取啊,既然不属于顶层对象Window,那就不加 window(global),直接访问即可。
- let不能重复声明
2.3 练习
<script>
console.log(fn); // undefined
window.fn(); // TypeError: window.fn is not a function
console.log(window.fn());
// 如果函数在if语句中(块级作用域),只提升变量名
if ('fn' in window) {
fn();
function fn() {
console.log('fn.....');
}
}
fn();
</script>
<script>
fn(); // 5
function fn() { console.log(1); }
fn(); // 5
function fn() { console.log(2); }
fn(); // 5
var fn = function fn() { console.log(3); }
fn(); // 3
function fn() { console.log(4); }
fn(); // 3
function fn() { console.log(5); }
</script>
2.4 闭包
闭包是指有权访问另外一个函数作用域中的变量的函数。
闭包的特点:
1)保护:数据私有化,外界访问不了,防止被全局变量污染
2) 保存:延长数据的生命周期
3)闭包使用不当可能会导致内存泄漏
使用场景:
- 模块封装,在ES6之前,都是这样的防守i仿制变量污染全局。
- 数据私有化
- 封装一些工具函数
- 在循环中创建闭包,防止取到意外值
<script>
var i = 5;
function fn(i) {
return function (n) {
console.log(n + (++i));
}
}
var f = fn(1);
fn(2);
fn(3)(4); // 8
fn(5)(6); // 12
f(7); // 9
</script>
<script>
var i = 20;
function fn() {
i -= 2; // 这里的i因为var所以是 undefined - 2 = NaN
var i = 10;
return function (n) {
console.log((++i) - n);
}
}
var f = fn();
f(1); // 10
f(2); // 10
fn()(3); // 8
console.log(i); // 20
</script>
2.5 IIFE
立即调用函数表达式,写法:
<script>
// 写法一
(function fn(){
console.log('fn....')
})()
// 写法二
(function fn(){
console.log('fn....')
}())
// 写法三(前面写加减)
+function fn(){
console.log('fn....')
}()
</script>
举例:
<script>
var myObject = {
num: 2,
add: function () {
this.num = 3;
console.log(this); // 该对象
(function () {
console.log(this.num); // undefined
console.log(this); // window
this.num = 4;
})();
console.log(this.name); // undefined
}
}
myObject.add();
console.log(num); // 4
</script>
<script>
(function () {
a++;
console.log(a); // NaN
var a = 20;
})();
console.log(a); // ReferenceError: a is not defined
</script>
<script>
(function () {
var x = foo(); // TypeError: foo is not a function
var foo = function foo() {
return 'foobar';
};
return x;
})()
</script>
欢迎关注我的公众号:丹星X,更多精彩~~