在面向对象的程序开发中,this通常指的是当面的对象,在javascript里,this对象是在运行时基于函数环境绑定的。所以this的值也是动态的,this指向当前函数的所有者对象,在运行时才能确定具体的指向,本文从this应用的几种场景分析this的指向问题。
场景一:全局函数情况下,函数声明
var name="honey";
function compare(value1,value2){
var name="shirly";
alert(this.name);
var s=value1+value2;
}
compare(1,2); /*输出的是honey*/
函数在执行时都会创建一个window对象的执行环境,存储函数可以访问的作用域里的变量及对象,实际调用是window.compare(1,2);在全局调用下可以省略window;
场景二:函数作为对象的方法调用
var name="honey";
var person={
name:'sally',
gender:'girl',
say:function(){
alert(this.name);
}
}
person.say(); /*输出的是sally*/
函数作为对象里的方法在调用,所以this指的是对象;还有另外一种方式就能看出this的动态性了;
Var test=person.say;
Test(); //这样输出的是honey,此时调用函数的对象就是window了
还有一种特殊的闭包形式:
var name="honey";
var person={
name:'sally',
say:function(){
alert(this.name);
return function(){
alert(this.name);
}
}
}
person.say()(); //honey,person.say()运行时闭包函数申明,所以闭包函数的调用对象还是window
从这里看出就是this指向的是运行时调用函数的对象,
场景三:构造函数里使用this
function person(name,age,job){
this.name=name;
this.age=age;
this.job=job;
this.sayName=function(){
alert(this.name);
};
}
var person1=new person("niki",29,"softWare");
实例化后this就指向了新new的这个对象
场景四:call,apply修改this对象的指向
每个函数都包含这个两个非继承而来的方法,这两个方法的用途就是在特定的作用域内调用函数,可以扩充函数赖以运行的作用域,对象不需要与方法有任何的耦合关系,
var name="sdsd";
var o={name:"shirly"};
function compare(){
alert(this.name);
}
compare(); //sdsd
compare.call(this); //sdsd
compare.call(window) //sdsd
compare.call(o) //shirly
call和apply的方法的不同就是后面参数的不同,call需要都逐个列举出来,apply只需要传入arguments对象
本来想理出看看this在函数作用域链里的搜索路径来确定this对象指向,但是貌似没有总结不出来,所以把this出现的情况总结下,然后记住:
关于this的指向问题,牢记住指向调用这个函数或方法的对象。