开始从js的this对象说起,this对象就是函数执行的环境对象。
我们来看下面的代码:
var name="Jack";
function GetName() {
console.log(this.name);
}
var obj = {name:"Tom"};
obj.GetNames=GetName;
GetName();
obj.GetNames();
GetName函数是在全局环境中定义,所以直接调用函数this就指向了全局环境,所以输出Jack。
之后我们定义了一个obj对象,然后也定义了一个属性GetNames,并赋值了GetName这个函数的指针。(注意函数不加后面()的时候,那时候就不是调用,那只是一个包含函数指针的变量)
由于函数执行环境变成了obj对象,所以this只想就指向了obj,所以自然就输出了“Tom”。
es5提供了三个函数非继承的方法,可以直接改变this的指向,但是在书中说是扩充函数作用域,但是我认为改变this指向更贴切一点。
因为如果是扩充函数作用域,就不用加this来访问,但是我测试的是,必须加上this才能访问到扩充的作用域。
三个方法分别为:apply,call,bing,用法都比较简单,作用也都是改变函数的this指向,下面我就用代码来简单说明一下。
1:apply
var name="Jack";
function GetName() {
console.log(this.name);
}
var obj = {name:"Tom"};
GetName.apply(obj,["param1","param2"]);
apply方法接受两个参数,第一个参数就是运行函数的作用域,可以理解为就是this,第二个就是参数数组,可以为Array的实例或者是数组,如果没有参数,可不传。
运行结果自然也是输出“Tom”。
2:call
var name="Jack";
function GetName() {
console.log(this.name);
}
var obj = {name:"Tom"};
GetName.call(obj,"param1","param2");
call和apply唯一不同的在于参数的传递,call就不止接受两个参数,参数的多少看你的父函数需要多个参数,因为call必须要把参数逐个传进去,不能使用数组或者是Array。
3:bind
var name="Jack";
function GetName() {
console.log(this.name);
}
var obj = {name:"Tom"};
var Clone_GetName=GetName.bind(obj);
Clone_GetName();
bind方法只需要传入一个参数,那就是this,然后返回一个函数,我们可直接调用。
这三个方法功能都是相同,都是改变this指向,只是使用形式上有一点不同,大家可灵活运用。