2021.11.3:JS(七):方法
对象中的函数称为方法。
定义
var 对象名 = { 属性1:值1, 属性2:值2, ... 方法名 : function() { ... } };
在每个方法内部,有个特殊变量this,始终指向当前对象。即用this.xxx可以拿到当前对象的其他属性。
需要注意的是,JS中如果在调用一个全局函数,那么这个函数中的this指向的是window。
为了能够及时暴露这个错误,strict模式下,函数(注意是函数而非方法)的this指向undefined。
此外,如果方法内部又额外定义了一个函数,那么在这个函数内部仍然不能用this指向当前对象。就像下边这样:
var xiaoming = { .... age: function () { function getAgeFromBirth() { var y = new Date().getFullYear(); return y - this.birth; } return getAgeFromBirth(); } };
修复的方法是,在方法内部额外定义一个变量,用它来捕获this:
var xiaoming = { ... age: function () { var that = this; // 在方法内部一开始就捕获this function getAgeFromBirth() { var y = new Date().getFullYear(); return y - that.birth; // 用that而不是this } return getAgeFromBirth(); } };
apply
虽然在一个独立的函数调用中,根据是否是strict模式,this指向undefined或window,不过我们还是可以控制this的指向的。
要指定函数的this指向哪个对象,可以用函数本身的apply方法,它接收两个参数,第一个是需要绑定的this变量,第二个参数是Array,表示函数本身的参数。
用apply修复getAge()调用:
function getAge() { var y = new Date().getFullYear(); return y - this.birth; } var xiaoming = { name: '小明', birth: 1990, age: getAge }; xiaoming.age(); // 25 getAge.apply(xiaoming, []); // 25, this指向xiaoming, 参数为空
所以,通过修改apply的第一个参数,来说明这个方法是指向哪个对象的。
另一个与apply()类似的方法是call(),唯一的区别是:
- apply()把参数打包为Array再传入;
- call()把参数按照顺序传入。
比如调用Math.max(3,5,4),分别调用apply()和call()实现如下:
Math.max.apply(null, [3, 5, 4]); // 5 Math.max.call(null, 3, 5, 4); // 5
对于普通函数调用,我们通常把this绑定为null。
装饰器
利用apply(),我们还可以动态改变函数的行为。
JS的所有对象都是动态的,即使是内置函数,我们也可以重新指向新的函数。
比如我们想统计函数parseInt()的调用次数,最佳方案就是用我们自己的函数替换掉默认的parseInt():
var count=0; var oldParseInt = parseInt; //保存原函数 window.parseInt = function () { count += 1; return oldParseInt.apply(null,arguments);//调用原函数 }; // 测试: parseInt('10'); parseInt('20'); parseInt('30'); console.log('count = ' + count); // 3