JS基础之作用域和闭包

    技术2025-08-14  24

    作用域:一个变量可以作用的函数代码快就是这个变量的作用域。

    全局作用域

    直接编写在script标签中的JS代码,都在全局作用域中。全局作用域在页面打开时创建,在页面关闭时销毁。在全局作用域中有一个全局对象window,他代表一个浏览器窗口,有浏览器创建,我们可以直接使用。在全局作用域中创建的变量都会作为window对象的属性来保存。创建的函数都会作为window的方法。全局作用域中的变量,在任意地方都可以被访问到。
    变量声明提前

    使用var关键字声明变量,会在所有所谓代码执行之前被声明,但是不会赋值。

    函数声明提前
    fun2(); // 会报错,因为fun2只是声明了,还没有赋值 fun() // 不会报错 function fun(){ // 这种方式创建函数会在所有的代码执行之前被创建 console.log("aaa"); } var fun2 = function(){ console.log("bbb"); }

    函数作用域

    在调用函数时,创建函数作用域,函数执行结束时销毁函数作用域,每个函数都有自己的独立作用域。函数外部不能访问函数内部的变量。就近原则,在函数作用域中操作变量,会先在自己的作用域种寻找变量,依次向上级寻找变量。如果在全局作用域中依然没有找到,会报错:ReferenceError函数作用域中也会有声明提前的特性。在函数作用域中如果不用var关键字声明变量,就会是一个全局变量

    this

    解析器在调用函数时会像函数内部传递一个隐含参数–this this称为函数执行的上下文对象

    以函数的方式调用时,this就是指window以方法的方式调用时,就是指的这个方法的对象

    闭包

    什么是闭包:闭包是指有权访问另一个函数作用域中变量的函数
    闭包的产生:创建一个函数,函数内部创建一个属性,如果外部可以访问这个属性,就产生了一个闭包。
    // 闭包1 function fun1(){ var num = 10; function fun2(){ // 可以调用fun1的局部变量 console.log(num); } fun(); } // 闭包2,实现全局作用域访问局部变量 function fun1(){ var num = 10; // 直接返回一个匿名函数 return function(){ // 可以调用fun1的内部属性 console.log(num); } // return fun2; } var f= fun1; f();
    闭包的作用:延伸了变量的作用范围

    例子:使用闭包实现三秒后打印出所有内容

    // lis是获取的所有li标签 var lis = document。getElementsByTagName['li']; for(var i = 0;i < lis.length; i++){ // ()(); 立即执行函数 (function(i){ setTimeout(function(){ // 定时器里的i是立即执行函数的i,也形成了闭包 console.log(lis[i],innerHTML); },3000) })(i); }

    思考题 思考打印结果是什么,是否有闭包?

    var name = "this window"; var object = { name: "my object"; getNameFunc: function(){ return function(){ return this.name; } } } console.log(object.getNameFunc()()); // this window ; 没有闭包 // 分析 var f = object.getNameFunc(); // 相当于 f = function(){ return this.name; } f(); // 就类似于function(){this}(); 这是立即执行函数,this指向是window //**********************************************************// var name = "this window"; var object = { name: "my object"; getNameFunc: function(){ var that = this; return function(){ return this.name; } } } console.log(object.getNameFunc()()); // my object; 存在闭包 // 分析 // 因为是object调用的getNameFunc,所以this指向onject,that就等于object,所以打印my object var f = object.getNameFunc(); // 相当于 f = function(){ return that.name; } f()
    Processed: 0.018, SQL: 10