javascript 闭包的理解

简介: 1,什么是闭包 “官方”的解释是:所谓“闭包”,指的是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。官方的解释实在是太高大上了,反正我是没有理解。

1,什么是闭包

  “官方”的解释是:所谓“闭包”,指的是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。

官方的解释实在是太高大上了,反正我是没有理解。闭包简单理解就是函数定义和函数表达式位于另一个函数的函数体内。而且,这些内部函数可以访问它们所在的外部函数中声明的所有局部变量、参数和声明的其他内部函数。当其中一个这样的内部函数在包含它们的外部函数之外被调用时,就会形成闭包。说的在直白一点就是当function嵌套function的时候,内部函数可以访问外部函数里面的变量。

可以把闭包和面向对象结合起来,把闭包的外部函数想象成一个class,外部函数里面的变量想象成私有变量,闭包函数想象成一个普通方法,如果想实现某种逻辑的话,可以在普通方法里面实现,去实例化外部函数并调用普通方法即可, 我觉得这样更容易理解闭包。

闭包的作用就是在a执行完并返回后,闭包使得Javascript的垃圾回收机制GC不会收回a所占用的资源,因为a的内部函数b的执行需要依赖a中的变量。

接下来让我们先来看个例子

function fun(){
  var n=0;
  this.plus = function(){
      return n+=1;
  }  
}

var _fun = new fun();
console.log(_fun.plus())
console.log(_fun.plus())
console.log(_fun.plus())

 

上面的demo就是个闭包,有权限访问另一个函数作用域内变量的函数都是闭包,因为变量n一直被plus引用,因此会一直在内存中存在不会被回收。(由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题。

2,闭包的几种方式

// 第一种
function add1(){
    this.counter = 0;
}
// 在Javascript中每个函数都有一个Portotype属性,而对象没有,这个我们后面用面向对象再来解释
add1.prototype.plus=function(){
    return this.counter+=1;
}
var _add1 = new add1();
console.log(_add1.plus())
console.log(_add1.plus())
// 第二种
var add2 = function(){
    var obj = {};
    obj.counter = 10;
    obj.plus = function(){
        return this.counter+=1;
    }
    return obj;
}
var _add2 = new add2();
console.log(_add2.plus())
console.log(_add2.plus())

// 第三种
var add3 = new Function("this.counter = 20;this.plus = function(){return this.counter+=1;}");
var _add3 = new add3();
console.log(_add3.plus())
console.log(_add3.plus())
// 第四种
var add4={
    "counter":30,
    "plus":function(){
        return this.counter +=1;
    }
}
console.log(add4.plus())
console.log(add4.plus())
// 第五种 自调用函数
var add5 = (function(){
    var counter = 40;
    return function(){
        return counter += 1;
    }
})()
console.log(add5())
console.log(add5())

3,prototype 让我们用面向对象的方式来解释

上面第一种方法中使用到了prototype,这里我们来说下如何理解它。

var obj = function(){
        
};
obj .show = function(){
    alert("我是静态方法");
};
obj .prototype.display = function(){
    alert("我是实例方法");
};
obj.
display(); // obj.Display is not a function
obj.show(); //正确

var _obj = new obj();
_obj.display(); //正确
_obj.show(); //_obj.Show is not a function

   1、不使用prototype属性定义的对象方法,是静态方法,只能直接用类名进行调用!另外,此静态方法中无法使用this变量来调用对象其他的属性!
   2、使用prototype属性定义的对象方法,是非静态方法,只有在实例化后才能使用!其方法内部可以this来引用对象自身中的其他属性!

 

4,作用域

var dom = function(){
        var Name = "Default";
        this.Sex = "Boy";
        this.success = function(){
            alert("Success");
        };
    };

    alert(dom.Name); // Undefined
alert(dom.Sex);
//Undefined

在Javascript中每个function都会形成一个作用域,而这些变量声明在函数中,所以就处于这个函数的作用域中,外部是无法访问的。要想访问变量,就必须new一个实例出来。

最后再来让我们看一个闭包的例子

// 闭包
var person = (function(){
    var name="default"; //变量作用域为函数内部,外部无法访问
    return {
        getName:function(){
            return name;
        },
        setName:function(_name){
            name=_name;
        }
    }
})()

console.log(person.name)
console.log(person.getName())
person.setName("jhone")
console.log(person.getName())

// 顺便写个继承吧 var boy = function(){} boy.prototype = person; boy.prototype.say = function(){ console.log("my name is " + this.getName()); } var _boy = new boy(); _boy.setName("jack") _boy.say();

5, js 中的只读属性

// 只读属性 set get 是es5的中对象的特性
obj = {
    get x() {return 6},
    get y() {return 7}
};
console.log(obj.x)
console.log(obj.y)
obj = {};
Object.defineProperty(obj, "x", {value:4, writable:false}); //只读属性
console.log(obj.x)
// 使用闭包实现
var fun = (function(){
    var age = 27;
    return function(){
        return age;
    }
})();
console.log(fun())

 

开开心心编码,快快乐乐生活。
目录
相关文章
|
2月前
|
自然语言处理 JavaScript 前端开发
深入理解JavaScript中的闭包:原理与实战
【10月更文挑战第12天】深入理解JavaScript中的闭包:原理与实战
|
1月前
|
JavaScript 前端开发
js 闭包的优点和缺点
【10月更文挑战第27天】JavaScript闭包是一把双刃剑,在合理使用的情况下,它可以带来很多好处,如实现数据封装、记忆功能和模块化等;但如果不注意其缺点,如内存泄漏、变量共享和性能开销等问题,可能会导致代码出现难以调试的错误和性能问题。因此,在使用闭包时,需要谨慎权衡其优缺点,根据具体的应用场景合理地运用闭包。
111 58
|
1月前
|
缓存 JavaScript 前端开发
js 闭包
【10月更文挑战第27天】JavaScript闭包是一种强大的特性,它可以用于实现数据隐藏、记忆和缓存等功能,但在使用时也需要注意内存泄漏和变量共享等问题,以确保代码的质量和性能。
36 7
|
1月前
|
自然语言处理 JavaScript 前端开发
JavaScript闭包:解锁编程潜能,释放你的创造力
【10月更文挑战第25天】本文深入探讨了JavaScript中的闭包,包括其基本概念、创建方法和实践应用。闭包允许函数访问其定义时的作用域链,常用于数据封装、函数柯里化和模块化编程。文章还提供了闭包的最佳实践,帮助读者更好地理解和使用这一强大特性。
19 2
|
20天前
|
存储 缓存 自然语言处理
掌握JavaScript闭包,提升代码质量与性能
掌握JavaScript闭包,提升代码质量与性能
|
20天前
|
自然语言处理 JavaScript 前端开发
深入理解JavaScript中的闭包(Closures)
深入理解JavaScript中的闭包(Closures)
|
20天前
|
存储 自然语言处理 JavaScript
深入理解JavaScript的闭包(Closures)
深入理解JavaScript的闭包(Closures)
19 0
|
2月前
|
设计模式 JavaScript 前端开发
探索JavaScript中的闭包:从基础概念到实际应用
在本文中,我们将深入探讨JavaScript中的一个重要概念——闭包。闭包是一种强大的编程工具,它允许函数记住并访问其所在作用域的变量,即使该函数在其作用域之外被调用。通过详细解析闭包的定义、创建方法以及实际应用场景,本文旨在帮助读者不仅理解闭包的理论概念,还能在实际开发中灵活运用这一技巧。
|
2月前
|
缓存 JavaScript 前端开发
深入了解JavaScript的闭包:概念与应用
【10月更文挑战第8天】深入了解JavaScript的闭包:概念与应用
|
2月前
|
自然语言处理 JavaScript 前端开发
Javascript中的闭包encloure
【10月更文挑战第1天】闭包是 JavaScript 中一种重要的概念,指函数能够访问其定义时的作用域内的变量,即使该函数在其词法作用域之外执行。闭包由函数及其词法环境组成。作用域链和词法作用域是闭包的核心原理。闭包常用于数据隐藏和封装,如模块模式;在异步操作中也广泛应用,如定时器和事件处理。然而,闭包也可能导致内存泄漏和变量共享问题,需谨慎使用。