JS作用域

本文摘自《你不知道的js》,详细讲解了JavaScript的词法作用域、动态作用域的区别,函数作用域、块级作用域的使用,以及let关键字的特点。此外,还探讨了闭包的概念,如何利用闭包隐藏内部实现,以及ES6中的模块化机制,包括import和export的用法。最后,提到了JavaScript中的变量提升与垃圾回收,强调了块作用域在内存管理上的优势。
摘要由CSDN通过智能技术生成

摘录于《你不知道的js》(上)

1. 词法作用域

function foo(a) {
	var b = a * 2;
	function bar(c) {
		console.log( a, b, c );
	}
	bar( b * 3 );
}

foo( 2 ); // 2, 4, 12

词法作用域 对比 动态作用域

function foo() {
	console.log( a ); 
}
function bar() {
	var a = 3;
	foo();
}
var a = 2;
bar();  // 2

词法作用域让 foo() 中的 a 通过 RHS 引用到了全局作用域中的 a ,因此会输出 2 。

而动态作用域并不关心函数和作用域是如何声明以及在何处声明的,只关心它们从何处调用。换句话说,作用域链是基于调用栈的,而不是代码中的作用域嵌套,所以基于动态作用域,上面代码会输出 3

2. 欺骗作用域

function foo(str, a) {
	eval( str );
	console.log(a, b);
}
var b = 2;

foo('var b = 3;', 1);

严格模式下失效

3. 函数作用域

function fun() {
	var a = 1;
}

fun();
console.log( a ) // ReferenceError: a is not defined
// fun()函数创造的作用域相对于全局作用域是内层的,查找变量的定义的规律是往外层定义域找,而不是向内层定义域找

函数作用域的含义是指,属于这个函数的全部变量都可以在整个函数的范围内使用及复用(事实上在嵌套的作用域中也可以使用)。无法从外部直接访问函数作用域,除非使用闭包

4. 隐藏内部实现

隐藏内部实现也就是私有化,为什么要私有化变量和函数?

  • 权限控制
  • 规避冲突

如何隐藏内部实现?不急,先介绍几个私有化的工具

  1. 通过函数作用域
var a = 2;
( function foo(){
	var a = 3;
	console.log( a ); // 3
})();

console.log( a ); // 2

上面代码使用了函数表达式,避免了 foo 变量污染全局。 (function foo(){ … }) 作为函数表达式意味着 foo 只能在 … 所代表的位置中被访问,外部作用域则不行。

注意函数表达式可以是匿名的,而函数声明则不可以省略函数名

setTimeout( function() {
	console.log("I waited 1 second!");
}, 1000 )

但匿名函数表达式有一定的缺点,不太建议使用

  • 匿名函数在栈追踪中不会显示出有意义的函数名,使得调试很困难
  • 递归调用自身时会很麻烦
  • 不利于代码的可读性

建议使用

setTimeout( function timeoutHandler() { // <-- 快看,我有名字了!
	console.log( "I waited 1 second!" );
}, 1000 );

立即执行函数表达式 IIFE(Immediately Invoked Function Expression)有两

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值