1:this
跟大多数的语言一样,javascript的this总是指向一个对象,而具体指向哪个对象是在运行时基于函数的运行环境动态绑定的,而非被声明时的环境。
2:this的指向
除去不常用的evel和with的情况,this指向大概分为以下四种
- 1:作为对象的方法调用,
- 2:作为普通函数调用,
- 3:构造器调用,
- 4:Function.prototype.call或Function.prototype.apply调用
2.1:作为对象的方法调用
当函数作为对象的方法被调用时,this指向该对象;
var obj = {
a: 1,
getA:function () {
alert(this === obj);//true
alert(this.a)//a
}
};
obj.getA();
2.2:作为普通函数调用
当函数不作为对象的属性调用时,用普通的函数调用时,此时的this总是指向全局对象。在浏览器里全局对象就是window;
var name = "globalName";
var getName = function () {
return this.name;
};
console.log(getName());//输出:globalName
// 或者:
var myObject = {
name:"jiankui",
getName:function () {
return this.name;
}
};
var getName = myObject.getName ;
console.log(getName())//输出:globalName
2.3:构造器调用
除了一些内置的函数,大部分的javascript函数都可以当做构造器使用,构造器的外表跟普通的函数一模一样,区别在于调用的方式,当用new运算符调用函数时,改函数通常返回一个对象,构造器的this就指向这个返回的对象
var myClass = function () {
this.name= "jiankui";
};
var obj = new myClass();
console.log(obj.name);//jiankui
但是用new构造器时,还要注意一个问题,如果构造器显式的返回一个object类型的对象,那么此次运算结果最终会返回这个对象,而不是我们上面期待的this
var myClass = function () {
this.name= "jiankui";
return {//显式的返回一个对象
name: "jiankui2"
}
};
var obj = new myClass();
console.log(obj.name);//jiankui2
如果构造器不显式的返回任何数据,或者是返回一个非对象类型的数据,就不会造成上述困扰
var myClass = function () {
this.name= "jiankui";
return "jiankui2";
};
var obj = new myClass();
console.log(obj.name);//jiankui
2.4:Function.prototype.call或Function.prototype.apply调用
跟普通函数调用相比,用Function.prototype.call或Function.prototype.apply可以动态的改变传入函数的this
var obj1 = {
name:"jiankui",
getName:function () {
return this.name;
}};
var obj2 = {
name:"jiankui2"
};
console.log(obj1.getName());//jiankui
console.log(obj1.getName.call(obj2));//jiankui2
3:丢失的this
这是个经常遇到的问题,先看代码
var obj = {
name:"jiankui",
getName:function () {
return this.name;
}};
var getName2 =obj.getName;
console.log(obj.getName());//jiankui
console.log(getName2());//undefind
当调用obj.getName()时,getName被当做对象的方法调用,根据2.1提到的,this指向obj对象,所以obj.getName()输出jiankui。
当用另一个变量getName2()来引用obj.getName,并调用getName2()时,根据2.2提到的,此时是作为普通函数调用,this指向window,而我们的window没有定义,所以为undefined
4 call和apply
apply接收两个参数,第一个参数指定了函数体内this对象的指向,第二个参数为一个带下标的集合,可以为数组和类数组,apply方法把这个集合中的元素作为参数传入被调用的函数:
var func = function (a, b, c) {
console.log([a, b, c]);//[1,2,3]
};
//数组的三个值分别对应abc三个参数
func.apply(null,[1,2,3]);
call传入的参数数量不固定,跟apply相同的是,第一个参数也是代表函数体内的this指向,从第二个参数开始往后,每个参数被依次传入函数
var func = function (a, b, c) {
console.log([a, b, c]);//[1,2,3]
};
func.call(null,1,2,3);
网友评论