JS基础-作用域引发的血案
1. window(Global) 全局作用域
- 全局作用域,和script作用域
- 以var定义的变量在全局作用域中存活
- a变量的生命周期
- 行8:a初始化全局变量并且赋值为1
- 行16:函数内部定义了同样的a变量,但是对外部全局变量a没有起到任何作用
- 行30:在块作用域中重新定义赋值为10,最后a的值改为10
2. local本地作用域
- 函数内部定义的变量是本地作用域
3. Block 块作用域
- 利用{}定义的变量片段生产的变量为块定义板块
- if、while、for 等语句都会生成 Block 作用域:
- 块作用域的变量如果是使用var变量定义,那么会提升到上级本地作用域中
4. Script 作用域
var a=1 // 全局作用中的变量
let b =2 // 局部变量,存活在script中
const c =3 // 局部变量,存活在script中
console.log('a->',a)
console.log('b->',b)
console.log('c->',c)
console.log('window.a->',window.a)
console.log('window.b->',window.b)
console.log('window.c->',window.c)
/**
scope.html:11 a-> 1
scope.html:12 b-> 2
scope.html:13 c-> 3
scope.html:14 window.a-> 1
scope.html:15 window.b-> undefined
scope.html:16 window.c-> undefined
*/
- 这里为什么b,c在输出本身自己的变量时可以输入出,但是利用全局变量window获取的时候是获取不到呢??? 因为他们不在全局变量中,他们在script作用域中
- 所以可以肯定let和const不能定义全局变量
- 只能定义块变量,
- window.xxx=xxx 这种代码是有效的,因为特别创建的作用域的改变
- 在node环境中没有script作用域,所以有不同的设置
5. 闭包的重要性
- 闭包是 JS 的常见概念,它是一个函数返回另一个函数的形式,返回的函数引用了外层函数的变量,就会以闭包的形式保存下来。 下面例子中a被放在了闭包作用域内,导致a被私有化,
- 闭包也会实现数据的和方法的私有化和模块化
// myModule 存在属性中
// publicMethod // 他是公有化
// privateMethod 私有化
// privateVariable 私有化
const myModule = (function () {
let privateVariable = "我是私有的!";
function privateMethod() {
console.log(privateVariable);
}
return {
publicMethod: function () {
privateMethod();
},
};
})();// 他是一个自执行函数
myModule.publicMethod(); // 输出: 我是私有的!
myModule.privateMethod();
情况2:实现了的方法没有自执行
const myModule = function () {
let privateVariable = "我是私有的!";
function privateMethod() {
console.log(privateVariable);
}
return {
publicMethod: function () {
privateMethod();
},
};
};
// myModule是一个函数,要想使他有效,需要对这个函数进行执行myModule()
// 这个方法有一个返回值,是一个方法publicMethod
myModule().publicMethod();
console.log(myModule().privateVariable) // 这个方法中没有返回privateVariable值
console.log(myModule().privateMethod()) // 这个方法中没有privateMethod()方法
-
闭包的问题:就是会导致变量一直在闭包内存中存在,没有被释放,造成内存泄漏
-
解决方法:
1.及时释放闭包:手动调用闭包函数,并将其返回值赋值为null,这样可以让闭包中的变量及时被垃圾回收器回收。
3.使用立即执行函数:在创建闭包时,将需要保留的变量传递给一个立即执行函数,并将这些变量作为参数传递给闭包函数,这样可以保留所需的变量,而不会导致其他变量的内存泄漏。
var name = "The Window";
var object = {
name: "My Object",
getNameFunc: function () {
return function () {
debugger
return this.name;
};
},
};
console.log(object.getNameFunc()()); /// The Window
转载自:https://juejin.cn/post/7352770048514064435