Js面试之作用域与闭包


最近在整理一些前端面试中经常被问到的问题,分为vue相关、react相关、js相关、react相关等等专题,可持续关注后续内容,会不断进行整理~

作用域

作用域(scope)定义了程序中变量的可访问性和生命周期,在js中,作用域有两种主要的类型:词法作用域(Lexical Scope)和动态作用域(Dynamic Scope);

词法作用域

词法作用域又称静态作用域,是指作用域在代码编写阶段就确定的,与函数的定义位置有关。javascript使用词法作用域,函数的作用域在函数定义时就已经确定

var globalVariable = 'I am global'

function outer() {
   
	var outerVariabl = 'I am outer'
	function inner() {
   
		var innerVariable = 'I am inner'
		console.log(innerVariable) // 可以访问innerVariable
		console.log(outerVariable) // 可以访问outerVariable
		console.log(globalVariable) // 可以访问globalVariable
	}
	inner();
	console.log(innerVariable) // Error: innerVariable is not defined
}

outer()

动态作用域

动态作用域是在运行时根据调用链来确定的,与函数的调用位置有关。js不使用动态作用域,而是使用词法作用域

闭包

闭包(Closure)是指一个函数和其词法作用域的组合。当函数在词法作用域以外的地方被调用时,它仍然能够访问自己的词法作用域,形成了闭包。
或说

闭包(Closure)是指有权访问另一个函数作用域中变量的函数,即便是在外部函数执行完毕之后。

function outer() {
   
	var outerVariable = 'I am outer'
	function inner() {
   
	   console.log(outerVariable) // 形成闭包,可以访问outerVariable
	}
	return inner
}

var closureFunction = outer()
closureFunction() // 通过闭包访问outerVariable

闭包使用场景

封装私有变量

通过闭包,可以创建私有变量,只能通过闭包内部的函数访问,不会被外部直接访问到;

function counter() {
   
  var count = 0;
  return function() {
   
    count++;
    console.log(count);
  };
}

var increment = counter();
increment(); // 输出 1
increment(); // 输出 2

模块化开发

使用闭包可以创建模块,将相关的功能封装到一个闭包中,避免全局污染

var module = (function() {
   
	var privateVariable = 'I am private';

	function privateFunction() {
   
    	console.log('This is private')
    }
	
	return {
   
		publicVariable: 'I am public',
		publicFunction: function() {
   
			console.log('This is public')
		}
	}
})()

console.log(module.publicVariable) // I am public
module.publicFunction() // This is public

保持变量状态

由于闭包可以访问外部函数的变量,所以可以保持状态

function createCounter() {
   
	var count = 0;
	return {
   
		increment: function() {
   
			count++;
			console.log(count)
		},
		reset: function() {
   
			count = 0;
			console.log('Count reset')
		}
	}
}

var counter = createCounter();
counter.increment(); // 输出1
counter.increment(); // 输出2

异步操作

在异步回调中经常使用闭包来保存状态

function fetchData(url, callback) {
   
	var data = null;
	
	fetchDataFromServer(url, function(result)) {
   
		// 调用 fetchDataFromServer 函数从服务器异步获取数据,并传给data
		data = result;
		callback();
	});
	
	return function() {
   
		// 使用闭包中的data
		console.log(data);
	}
}

var getData = fetchData('https://example.com/data', function() {
   
	console.log('Data received');
})

// 在合适的时机调用getData()

注意事项

  • 潜在的内存泄漏问题:如果闭包中引用了大量变量,可能导致内存无法释放。
  • 滥用闭包可能导致性能问题,因为它们会占用更多内存

相关推荐

  1. Js面试作用

    2024-01-19 08:22:02       37 阅读
  2. js面试---作用作用链、执行上下文

    2024-01-19 08:22:02       15 阅读
  3. js进阶-es6-作用-垃圾回收机制--变量提升

    2024-01-19 08:22:02       18 阅读
  4. 1-1.this指针&&作用

    2024-01-19 08:22:02       37 阅读
  5. Vue js

    2024-01-19 08:22:02       13 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-01-19 08:22:02       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-01-19 08:22:02       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-01-19 08:22:02       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-01-19 08:22:02       20 阅读

热门阅读

  1. STL-string

    2024-01-19 08:22:02       31 阅读
  2. c++学习之特殊类设计与类型转换

    2024-01-19 08:22:02       36 阅读
  3. Qt中ListWidget控件总结

    2024-01-19 08:22:02       40 阅读
  4. ArrayList和LinkedList的区别

    2024-01-19 08:22:02       38 阅读
  5. MATLAB Fundamentals>>>Creating Datetimes

    2024-01-19 08:22:02       33 阅读
  6. linux安装hadoop详细步骤

    2024-01-19 08:22:02       40 阅读
  7. SOH 均衡技术发展方向及建议

    2024-01-19 08:22:02       32 阅读
  8. [go] 适配器模式

    2024-01-19 08:22:02       30 阅读
  9. Docker初步使用

    2024-01-19 08:22:02       34 阅读