你不知道的JS(上卷)——读书笔记6 动态作用域、块作用域的替代方案、this词法

附录A

动态作用域

大部分语言都是基于词法作用域,JS也是词法作用域
词法作用域是在代码编写时就已经确定好了的(取决于代码编写的位置),除了eval和with
而动态作用域关心的是函数在何处被调用

总结来说,动态作用域的作用域链是基于调用栈的(函数的调用栈),而词法作用域的作用域链是基于作用域的嵌套

附录B

块作用域的替代方案

想要在ES6之前只用块作用域,可以使用catch:

try{throw:2;}catch(a){
	console.log(a);	//2
}

这段代码虽然可以达到块作用域的效果,但是看起来很不舒服。但是重点是,工具可以将我们写的ES6语法转换为能在ES6之前环境中的代码形式(就像刚才的代码),我们只要在构建时通过工具对代码进行预处理就好了

附录C

this词法

一般写代码会遇到下面问题:

var obj = {
	id:'awesome',
	cool:function coolFn(){
		console.log(this.id);
	}
};

var id = 'not awesome';

obj.cool();	//awesome

setTimeout(obj.cool,100);	//not awesome

可知,当把obj.cool当做回调函数传入setTimeout时,已经丢了this和该函数之间的绑定。setTimeout函数中调用了比如callback之类的函数,而此时this已经绑定到了window(全局)对象中,所以打印的结果是not awesome

其中,ES6的箭头函数是解决方案之一:

var obj = {
	count:0,
	cool:function coolFn(){
		if(this.count<1){
			setTimeout(()=>{
				this.count++;
				console.log('awesome?');
			},100);
		}
	}
}

obj.cool();	//awesome?

箭头函数可不只是省略function关键词那么简单,其对于this绑定的行为和普通函数是完全不一样的,它是用当前的词法作用域覆盖了this本来的值
但是,据作者所言,箭头函数混淆了this绑定规则和词法作用域规则,并且其只能作为匿名函数,在他看来并不是最合适的解决方案

有一种是作者所推荐的,至少比箭头函数要好:

var obj = {
	count:0,
	cool:function coolFn(){
		if(this.count<1){
			setTimeout(function timer(){
				this.count++;
				console.log('awesome?');
			}.bind(this),100);
		}
	}
}

obj.cool();	//awesome?

这种bind的写法可以手动修改this值的绑定

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值