javascript是一门解释型的语言,与很多面向对象语言相比有着不同特性,所以不能用面向对象的原理来理解this这个关键字。
在JS中,要真正理解this倒底指向哪个对象,必须先了解JS的作用域和原型链的原理。简单的说,this是与运行时的执行环境绑定的。在使用它时,我们是无法确定其this指向哪个对象,只有当真正调用时,this才会指向所调用的对象。如以下代码
1
2
|
var a= "hi" ;
alert( this .a);
|
结果很明显,弹出一个"hi"窗口提示。
1
2
|
//var a="hi"; alert( this .a);
|
弹出一个"undefined"窗口提示。
上面两种结果,是由于JS默认作用域是window,即a在运行时指向的是当前window这个对象,前者window存在a这个实体属性,而后者没有。
那么再看一下下面例子
1
2
3
4
5
6
|
var a = "hi" ;
function say() { alert( this .a);
} say(); |
弹出一个"hi"窗口提示。
1
2
3
4
5
6
|
//var a ="hi"; function say() { alert( this .a);
} say(); |
弹出一个"undefined"窗口提示。
1
2
3
4
5
6
7
|
//var a ="hi"; function say() { var
a= "say hi" ;
alert( this .a);
} say(); |
弹出一个"undefined"窗口提示。
1
2
3
4
5
6
7
|
//var a ="hi"; function say() { a= "say hi" ;
alert( this .a);
} say(); |
弹出一个"say hi"窗口提示。
以上四个例子中,this虽然定义在say这个函数下,但函数的调用对象还是windows,1和2理解和上两个例子差不多,第3和第4则是由于作用域导致的。第3个a的作用域在仅函数里,第4中a的作用域为window(未定义直接初始化,变量作用域属于它的调用对象)。
再来点示例:
1
2
3
4
5
6
|
function say() { this .a= "say hi" ;
} var who= new
say();
alert(who.a); |
弹出一个"say hi"窗口提示。
以上这个例子在运行时,this指向的是who这个实体,如果直接运行say()那么结果将是弹出一个"undefined",因为say()只是个函数(相当于面向对里里面的类),而new say()是一个对象,相当于面向对象里的类的实例。
说完this,下面再来整下JS里在很多框架内部源码经常看到的两个常用关键字:call.apply。其它这两个方法可以说是一个功能,只是传的参数形式不一样, xxFunction.call(A,arg,arg),xxFunction.apply(A,args)。简单的说就是调用对象来执行方法。作用,运行时辅助操作对象,常用于继承操作。
如下列代码:
1
2
3
4
5
6
7
8
9
|
function User(name){ this .name=name;
} function Coder(name){ User.call( this ,name);
this .skill= "Code" ;
} var coder = new
Coder( "xiaoming" );
alert(coder.name+ "擅长" +coder.skill);
|
Code继承于User,并有自己的skill属性。