文章目录 前言一、什么是闭包二、使用场景1. 修改字号的例子2. 柯里化函数3. 使用闭包模拟私有方法 三、注意事项本系列主要整理前端面试中需要掌握的知识点。本节介绍JS中的闭包。
一、什么是闭包
一个函数和对其周围状态的引用捆绑在一起(或者说函数被引用包围),这样的组合就叫闭包。
即闭包可以让你在一个内层函数中访问到其外层函数的作用域
function init() {
var name = "Mozilla"; // name 是一个被 init 创建的局部变量
function displayName() { // displayName() 是内部函数,一个闭包
alert(name); // 使用了父函数中声明的变量
}
displayName();
}
init();
虽然displayName()没有自己的局部变量,然而,由于闭包的特性,它可以访问到外部函数的变量。
二、使用场景 创建私有变量延长变量的生命周期 1. 修改字号的例子<body>
<p>在页面上添加一些可以调整字号的按钮p>
<button id="size-12">12pxbutton>
<button id="size-24">24pxbutton>
<button id="size-36">36pxbutton>
body>
html>
<script>
function makeSizer(size){
return function(){
document.body.style.fontSize = size + 'px'
}
}
let size12 = makeSizer(12);
let size24 = makeSizer(24);
let size36 = makeSizer(36);
document.getElementById('size-12').onclick = size12;
document.getElementById('size-24').onclick = size24;
document.getElementById('size-36').onclick = size36;
script>
2. 柯里化函数
柯里化的目的在于,避免频繁调用具有相同参数函数的同时,又能轻松的重用。
function getArea(width){
return height=>{ //返回函数的参数为height
return height*width
}
}
const setWidthIs10 = getArea(10) //得到一个函数,宽度固定为10
const Area1 = setWidthIs10(40) //为宽度为10的函数提供高度:40
console.log(Area1);
const Area2 = setWidthIs10(20) //为宽度为10的函数提供高度:20
console.log(Area2);
3. 使用闭包模拟私有方法
var Counter = function(){
var privateCounter = 0;
function changeBy(val){
privateCounter += val;
}
return {
increment:function(){
changeBy(1);
},
decrement:function(){
changeBy(-1);
},
value:function(){
return privateCounter;
}
}
};
var Counter1 = Counter();
var Counter2 = Counter();
console.log(Counter1.value()); //0
Counter1.increment();
Counter1.increment();
console.log(Counter1.value()); //2
Counter2.decrement();
console.log(Counter2.value()); //-1
Counter1.decrement();
console.log(Counter1.value()); //1
两个计数器 Counter1 和 Counter2 是维护它们各自的独立性的,每次调用其中一个计数器时,通过改变这个变量的值,会改变这个闭包的词法环境,不会影响另一个闭包中的变量
三、注意事项如果不是某些特定任务需要使用闭包,在其他函数中使用闭包是没有必要的,因为闭包的处理速度和内存消耗方面对脚本性能有负面影响。在创建新的对象或者类时,方法通常应该关联于对象的原型,而不是定义到对象的构造器中。
function MyObject(name, message) {
this.name = name.toString();
this.message = message.toString();
this.getName = function() {
return this.name;
};
this.getMessage = function() {
return this.message;
};
}
//上面的代码中并没有利用到闭包的好处,因此要避免使用闭包,修改如下:
function MyObject(name, message) {
this.name = name.toString();
this.message = message.toString();
}
MyObject.prototype.getName = function() {
return this.name;
};
MyObject.prototype.getMessage = function() {
return this.message;
};
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)