JavaScript的this一直是容易让人误用的关键词,尤其对于熟悉Java的程序员来说,因为JavaScript中的this与Java中的this是有很大不同的。在一个function的执行过程中,如果在变量的前面加上了this作为前缀,如this.myVal,对此变量的求值就从this所表示的对象开始。
this的值取决于function被调用的方式,一共有5种:
❑如果一个function是一个对象的属性,那么在funtion被调用时,this的值是这个对象。
❑如果function调用的表达式包含句点(.)或,那么this的值是句点(.)或之前的对象。如在myObj.func和myObj["func"]中,func被调用时的this是myObj。
❑如果一个function不是作为一个对象的属性,那么在function被调用时,this的值是全局对象。当一个function中包含内部function时,不理解this的正确含义就很容易造成错误,因为内部function的this值与它外部的function的this值是不一样的。
var myObj={
myVal:"Hello World",
func:function{
alert(typeof this.myVal);//string
var self=this;
function inner{
alert(typeof this.myVal);//undefined
alert(typeof self.myVal);//string
}
inner;
}
};
myObj.func;
在myObj函数体内有个内部名为inner的函数,在inner被调用时,this的值是全局对象,因此找不到名为myVal的变量。这时通常的解决办法是将外部function的this值保存在一个变量中(此处为self),在内部函数中使用它来查找变量。
❑如果在一个function之前使用new,则会创建一个新的对象,该funtion也会被调用,而this的值是新创建的那个对象。
function User(name){
this.name=name
};
var user1=new User("Alex");
调用new User("Alex")会创建一个新的对象,以user1来引用,User这个function也会被调用,会在user1这个对象中设置名为name的属性,其值是Alex。
❑如果通过function的apply和call方法来指定它被调用时的this的值,那么apply和call的第一个参数都是要指定的this值,两者不同的是调用的实际参数在apply中是以数组的形式作为第二个参数传入的,而在call中除了第一个参数外其他参数都是调用的实际参数。
JavaScript中并没有Java或C++中的类的概念,而是采用构造器的方式来创建对象。在new表达式中使用构造器就可以创建新的对象。由构造器创建出来的对象有一个隐含的引用指向该构造器的prototype。
所有的构造器都是对象,但并不是所有的对象都能成为构造器。能作为构造器的对象必须实现隐含的Construct方法。如果new操作符后面的对象并不是构造器,会抛出TypeError异常。
new操作符会影响function调用中return语句的行为。当调用function时有new作为前缀,如果返回的结果不是一个对象,那么新创建的对象将会被返回。
function user(name){
this.name=name;
}
function anotherUser(name){
this.name=name;
return{
"badName":name
};
}
var u1=new User("Alex");
alert(typeof u1.name);//string
var u2=new anotherUser("Alex");
alert(typeof u2.name);//undefined
alert(typeof u2.badName);//string
在上面代码中,函数anotherUser通过return语句返回了一个对象,因此u2引用的是返回的那个对象;而函数user并没有使用return语句,因此u1引用的是新创建的User对象。