持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第1天,点击查看活动详情
JS函数特点
默认参数
当一个JS函数被调用时,除了函数显示提供的形参之外,还有两个默认的参数会被默认传递给函数体
函数的上下文关联的对象:this
在普通的面向对象语言比如Java中,this通常表示当前对象的一个引用,但在JS中由于函数调用方式或者说执行环境不同,this指针的指向也会随之变化也就是所谓的运行时绑定。
文章后半部分会分情况来讨论this指向的原则。
函数参数列表:arguments:
它是一个类数组的结构,但不是数组,我们可以使用下标访问里面包含的参数,避免在严格模式下使用。
参数不确定性
不管函数定义了几个形参,你其实可以随便传,比如形参有两个你可以一个都不出传,默认为undefined,也可以只传一个,另一个参数就是undefined,也可以传3个或者更多。多余的参数可以在默认的arguments参数中获取。
调用方式
函数有如下几种调用方式:
- 在全局中作为一个函数被调用。
- 作为实例对象的一个方法被调用
- 作为一个构造函数被调用:new XXXFunc()
- 通过函数的apply或者call方法调用
this指针指向
面向对象语言中 this 表示当前对象的一个引用。
但在 JavaScript 中 this 不是固定不变的,它会随着执行环境的改变而改变。
函数作为一个函数被调用时
- 非严格模式下,this指向window对象
- 严格模式下,this为undefined
- 无论是否在严格模式下,在全局执行环境中(在任何函数体外部)
this都指向全局对象(浏览器中全局对象就是window) - 可以使用
globalThis获取全局对象,无论你的代码是否在当前上下文运行。 比如在浏览器中
在node环境中
函数作为一个对象的方法被调用时
1、this指向其宿主即调用该函数的对象,比如下面代码,this指向man
var man = {
age: 30,
howOldAreU: function() {
return this.age;
}
};
console.log(man.howOldAreU()); // 30
2、标签事件中,当点击调用对象buttonObj的方法click的时候,上下文this被强制设为button标签
函数作为一个构造函数被调用时
在类的构造函数中,this 指向该类新创建的对象。类中所有非静态的方法都会被添加到 this 的原型中。这和Java比较像,指向类的实例对象,该实例对象并不拥有这个类的静态方法。
通过函数的apply或者call方法调用
function sumAll(){
var sum = 0;
for(let n = 0; n<arguments.length; n++){
sum += arguments[n];
}
this.num = sum;
}
var obj1 = {};
var obj2 = {};
//使用apply方法指定函数上下文为obj1
sumAll.apply(obj1,[1,2,3,4,5,6,7,8]);
//使用call方法指定函数上下文为obj2
sumAll.call(obj2,1,2,3,4,5,6,7,8);
console.log(obj1.num);//36
console.log(obj2.num);//36
函数使用bind方法指定this的指向
所有函数均可访问bind方法,可以创建并返回一个新函数,并绑定在传入的对象上(在本例中,绑定在button对象上)。不管如何调用该函数,this均被设置为对象本身。被绑定的函数与原始函数行为一致,函数体一致。
比如早期我们开发React的时候在class组件中写一个方法,然后在初始化组件的时候需要做bind操作,否在无法使用this调用该方法。
在箭头函数中this的指向
箭头函数相比于传统的函数声明和函数表达式,可以更优雅地创建函数。箭头函数作为回调函数还有一个更优秀的特性:箭头函数没有单独的this值。箭头函数的this与声明所在的上下文的相同。
比如在React的class组件中使用箭头函数声明函数就无需再bind,this自动指向当前函数的上下文也就是所在的那个class组件。