「这是我参与2022首次更文挑战的第18天,活动详情查看:2022首次更文挑战」
前言
“就像我们说,读万卷书和行万里路,是静态和动态的互补一样。如果说人类的进化,是从行路开始的,那么人类的文明,毫无疑问依靠的是阅读”。最近发现自己很难静下心来读文字,这点需要纠正。今天学到了ECMAScript函数内部的两个特殊的对象:arguments 和 this。
arguments
这个对象之前也了解过了,它是一个类数组对象,包含调用函数时传入的所有参数,并且它只有以function关键字定义函数时才会有,虽然它主要用于包含参数,但是arguments对象其实还有一个callee属性,是一个指向arguments对象所在函数的指针。例如下面这个经典的阶乘函数:
function jc(num){
if(num <= 1){
return 1;
}else{
return num * jc(num - 1);
}
}
上述阶乘函数定义为了递归调用,它需要保证函数名为 jc ,这样就导致了紧密耦合。使用arguments.callee属性就可以让函数逻辑和函数名解耦:
function jc(num){
if(num <= 1){
return 1;
}else{
return num * arguments.callee(num - 1);
}
}
let anotherJc = jc;
jc = function(){
return 0;
};
console.log(anotherJc(5));//输出 120
console.log(jc(5));//输出 0
可以看到无论函数名称是什么,递归计算阶乘都可以正确计算。
this
另一个特殊的对象是 this,它在标准函数和箭头函数中又不一样的地方:
- 标准函数中,this指向的是把函数当成方法调用的上下文对象(在网页的全局上下文中调用函数时,this指向windows),例如:
windows.color = 'green';
let o = {
color: 'blue'
};
function showColor{
console.log(this.color);
}
showColor();//输出 'green'
o.showColor = showColor;
o.showColor();//输出 'blue'
可以看到this到底引用哪个对象要到函数被调用时才能确定,所以它的值在代码执行过程中会发生变化。
- 在箭头函数中,this引用的是定义箭头函数的上下文,比如:
windows.color = 'green';
let o = {
color: 'blue'
};
let showColor = () => console.log(this.color);
showColor();//输出 'green'
o.showColor = showColor;
o.showColor();//输出 'green'
可以看到两次调用,this引用的都是window对象,因为这个箭头函数是在window上下文中定义的。箭头函数中的this还会保留定义该函数时的上下文,所以在事件回调或者定时回调中调用某个函数时,想要保证this的指向正确就可以把回调函数写成箭头函数。例如:
function firstName(){
this.name = 'Tom';
setTimeout(() => console.log(this.name),1000);
}
function lastName(){
this.name = 'Jack';
setTimeout(function() { console.log(this.name);},1000);
}
new firstName();//输出 Tom
new lastName();//undefined
总结
静下心来读书吧,每次都会用新的收获!