概览
this关键字在Javascript中的表现和其他语言略有不同。在严格模式和非严格模式下同样存在区别。在大部分情形下,this的值由函数的调用方式所决定。
全局上下文
全局环境中,this指代全局对象,无论是否在严格模式。
console.log(this===window);//true
this.a=37;
console.log(window.a);//37
函数上下文
- 非严格模式下:
function f1(){
return this;
}
f1()===window; //true
- 严格模式下:
function f2(){
"use strict";
return this;
}
f2()===undefined;//true
在普通函数调用中,非严格模式下,并且没有用****call****或者****apply****指定****this****的值,那么****this****默认设置为全局变量;在严格模式下,****this****的值等于它进入执行作用域时被设定的值****.****在上例中****this****没有被赋予任何值,所以它等于默认值****undefined****
对象方法中的this
当以对象里的方法的方式调用函数时,它们的this是调用该函数的对象。
var object={
value:10,
getValue:function(){
return this.value;
}
};
console.log(object.getValue()); // 输出10
构造函数中的this
当一个函数被作为一个构造函数来使用(使用new关键字),它的this与即将被创建的新对象绑定。
var Person=function(){
this.age=20;
}
var mario=new Person();
console.log(mario.age); //输出20
call 和 apply
call 和 apply是为了动态改变this而出现的,当一个Object没有某个方法,但是其他的有,则可以借助call或apply用其他对象的方法来操作。
function printInfo(gender,age){
alert(this.name+" is a "+gender+" and "+age+" years old ");
}
var person={
name:"mario"
};
printInfo.call(person,"man","20");//mario is a man and 20 years old.
printInfo.apply(person,["man","20"]);//mario is a man and 20 years old.
call和apply的区别
foo.call(this,arg1,arg2,arg3)==foo.apply(this,[arg1,arg2,arg3])==this.foo(arg1,arg2,arg3)
//this是想指定的上下文
****JS****中,某个函数的参数数量是不固定的。所以当参数明确知道数量时,用****call****,而不确定的时候,用****apply****,然后将参数****push****进数组,当参数数量不确定时,函数内部也可以通过****arguments****这个数组来遍历所有的参数。
bind方法
ES5中引入了Function.prototype.bind. 调用f.bind(someObject)会创建一个与f具有相同函数体和作用域的函数,但是在这个新函数中,this将永久的被绑定到了bind的第一个参数,无论这个函数时如何被调用的。
function origin(){
return this.value;
}
var bind=origin.bind({value:"abcd"});
console.log(bind());// "abcd"
var object={value:100, origin:origin,bind: bind}
console.log(object.origin(),object.bind()); //100,"abcd"
上面这段代码首先声明了一个原有函数origin,然后用origin函数创建了一个与origin具有相同函数体和作用域的函数bind,在bind函数中,this被永久的绑定到了第一个参数也就是"abcd",所以在最后我们创建一个新的同时带有origin和bind函数的实例object后,origin函数中的this指代的是object本身,所以能输出object本身的value值100,但bind中的this已经无法改变,this.value将永远等于"abcd".
DOM中的this
当函数被用作事件处理函数时,它的this指向触发事件的元素。(这一点和前面对象方法中的this相似)
假设我们有一个id为"test"的按钮:
var button=document.getElementById("test");
button.setEventListener("click",function(){
alert(this.id); //输出了按钮的id:test
});
由此可见这里this指向的就是触发click事件的元素--id为“test”的按钮。
总结
综上所述,this出现的场景可以被分为四类:
- 有对象就指向调用对象(无论是对象方法中还是DOM中)
- 没调用对象就指向全局对象
- 用new构造的就指向被创建的新对象
- 通过apply或call或bind可以改变this的指向
网友评论