likes
comments
collection
share

JS基础-作用域引发的血案

作者站长头像
站长
· 阅读数 9

1. window(Global) 全局作用域

JS基础-作用域引发的血案

JS基础-作用域引发的血案

  • 全局作用域,和script作用域
  • 以var定义的变量在全局作用域中存活
  • a变量的生命周期
    • 行8:a初始化全局变量并且赋值为1
    • 行16:函数内部定义了同样的a变量,但是对外部全局变量a没有起到任何作用
    • 行30:在块作用域中重新定义赋值为10,最后a的值改为10

2. local本地作用域

  • 函数内部定义的变量是本地作用域 JS基础-作用域引发的血案

3. Block 块作用域

- 利用{}定义的变量片段生产的变量为块定义板块
- if、while、for 等语句都会生成 Block 作用域:
- 块作用域的变量如果是使用var变量定义,那么会提升到上级本地作用域中

JS基础-作用域引发的血案

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作用域,所以有不同的设置
  • JS基础-作用域引发的血案

5. 闭包的重要性

  • 闭包是 JS 的常见概念,它是一个函数返回另一个函数的形式,返回的函数引用了外层函数的变量,就会以闭包的形式保存下来。 下面例子中a被放在了闭包作用域内,导致a被私有化,

JS基础-作用域引发的血案

  • 闭包也会实现数据的和方法的私有化和模块化
// 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