在《JavaScript语言精粹》(蝴蝶书)中讲到函数除了声明定义的参数外,每个函数都接受两个附加的参数:this 和 arguments 。
其中this有四个调用模式:
this指向取决于谁调用它,谁调用指向谁。
- 方法调用模式
- 函数调用模式
- 构造器调用模式
- apply调用模式
方法调用模式
一个函数被保存为对象的一个属性时,称该函数为一个方法,此时this指向该对象,通过this去访问该对象的属性,取值或者修改;
1 | var myObj = { |
函数调用模式
当一个函数不是一个对象的属性时,而是单独存在时,那么它被当作一个函数调用,此时函数内部的this指向全局对象;
1 | var value = 1;//全局变量 |
假如该函数是一个函数的内部函数,那么其this应绑定其外部函数的this变量,即和外部this的指向相同,但是js并不是这样,这也是js设计的缺陷之一;在inner()中,this指向了全局对象,而不是指向了myObj;
1 | var value = 1;//全局变量 |
解决方法:在外部函数test中定义一个变量,赋值为this;
1 | test : function () { |
构造器调用模式
1 | var Person = function (str,num) { |
通过构造函数实例化一个新的对象时,构造函数中this会随之绑定到该新对象;
Apply 调用模式
每个函数都有call()和apply()方法
1 | obj.call(thisObj, arg1, arg2, ...); |
两者作用一致,都是把obj(即this)绑定到thisObj,这时候thisObj具备了obj的属性和方法。或者说thisObj『继承』了obj的属性和方法。
1 | function Cat() { |
arguments
它是一个类数组,有length的属性和index下标,没有数组的方法。
关于类数组以及如何利用call()、apply()使用数组方法等,可以看之前的文章:做了动物的战争web小游戏之后的总结
length & name
函数形参的数量
1 | const a = (b, c, d) => console.log(b); |
prototype
该函数的原型