JavaScript学习(3)——方法

在一个对象中绑定函数,称为该对象的方法。

在JS中,对象的定义是这样的:

var xiaoming = {
	name: '小明',
	birth: 1990
};

但是,如果我们给xiaoming绑定一个函数,就可以做更多的事情。比如, 写个age()方法,返回xiaoming的年龄:

var xiaoming = {
	name: '小明',
	birth: 1990,
	age: function () {
		var y = new Date().getFullYear();
		return y - this.birth;
	}
};

xiaoming.age;
xiaoming.age();

this指向当前对象。但是this在JS设计中是一个很坑的东西。要保证this的指向正确,必须用obj.xxx()的形式调用!
由于这是一个巨大的设计错误,要想纠正可没那么简单。ECMA决定,在strict模式下让函数的this指向undefined,因此,在strict模式下,你会得到一个错误:

'use strict';

var xiaoming = {
    name: '小明',
    birth: 1990,
    age: function () {
        var y = new Date().getFullYear();
        return y - this.birth;
    }
};

var fn = xiaoming.age;
fn(); // Uncaught TypeError: Cannot read property 'birth' of undefined

而且如果在方法的函数内部再指定函数,this又会指向undefined了(strict模式下)。this只在方法的函数中指向对象本身。
所以一个比较好的办法时,在方法的函数中先用一个变量that捕获this,然后在定义的函数中用that来代替this。

'use strict';

var xiaoming = {
	name : '小明',
	birth: 1990,
	age: function () {
		var that = this;//在方法内部一开始就捕获this
		function getAgeFromBirth() {
				var y = new Date().getFullYear();
				return y - that.birth;
		}
		return getAgeFromBirth();
	}
};

xiaoming.age(); //25

apply
虽然在一个独立的函数调用中,根据是否是strict模式,this指向不同的对象,但是其实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();
getAge.apply(xiaoming, []);

另一个类似的方法是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(),,可以通过替换函数来完成:

'use strict';

car 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

猜你喜欢

转载自blog.csdn.net/weixin_42595515/article/details/84563725
今日推荐