在《javaScript语言精粹》这本书中,把 this 出现的场景分为四类,简单的说就是:
有对象就指向调用对象;没调用对象就指向全局对象;用new构造就指向新对象;通过 apply 或 call 或 bind 来改变 this 的所指。
首先理解这句话:this对象是在运行时基于函数的执行环境绑定。
this引用是一种在JavaScript代码中随时都可以使用的只读变量,this引用的是一个对象。因此根据函数的调用方式不同,引用的对象也会有所不同。
this会根据代码的上下文语境自动改变其引用。
接下来看第一种情况:
1. 有对象就指向调用对象
var name = "this is gloabal";
var obj = {
name : "my object",
getName : function(){
return this.name;
}
}
alert(obj.getName()); //my object
函数的执行环境在obj内,所以访问的是obj.name;
2.没对象调用就指向全局对象
var name = " this is global";
function getName(){
return this.name;
}
alert(gertName()); //this is global
3. 用new构造函数就指向新对象
function getObj(){
console.log(this); //控制台输出: getObj{}
//this指向的新创建的getObj对象
}
new getObj();
}
4. 通过 apply 或 call 或 bind 来改变 this 的所指。
var name = 'this is window'; //定义window的name属性,看this.name是否会调用到
var testObj1 = {
name : 'this is testObj1',
getName:function(){
console.log(this);
console.log(this.name);
}
}
var testObj2 = {
name: 'this is testObj2'
}
//就相当于使testObj1.getName在testObj2的环境中运行。所以得到的是 this is testObj2
testObj1.getName.apply(testObj2);
//控制台输出: this is testObj2
testObj1.getName.call(testObj2);
最后有一种情况:
var obj={
name:'this is obj',
getname:function(){
return function(){
return this.name;
}
}
}
alert(obj.getname()());
obj.getname()执行返回的是一个 函数,两个括号就是要执行返回的函数。因为该函数是在windows作用域中执行的,
所以 这个this对象 指向的是windows作用域 而非 obj的作用域。
var name = "this is global";
var myObject = {
name : "my object",
getValue: function(){
var foo = function(){
alert(this.name);
}
foo();
}
}
myObject.getValue(); //this is global
在上述代码块中,foo 函数虽然定义在 getValue 的函数体内,但实际上它既不属于 getValue 也不属于 myObject。foo 并没有被绑定在任何对象上,所以当调用时,它的 this 指针指向了全局对象 global。
varname=’this is windows’;
varobj={
name:’this is obj’,
getname:(function(){
alert(this.name)
})();
}
同样 该代码 弹出 this is windows;
因为 getname函数会在页面加载的时候就执行,
而执行环境是在windows下执行的,所以this 指向的就是windows作用域。
千万不要理解为 写在obj体里就认为this对象肯定指向obj体。。这是错误的。。
this对象是在运行时基于函数的执行环境绑定。