JAVASCRIPT this关键字详解

##this指向哪里?

一般而言,this指向函数执行时的当前对象。

In JavaScript, as in most object-oriented programming languages, this
is a special keyword that is used within methods to refer to the
object on which a method is being invoked.

——jQuery Fundamentals (Chapter 2), by Rebecca Murphey

值得注意的是:该关键字在javascript执行环境中,而非声明环境中。

什么意思呢,举例说明:
例1:

	var name = 'window';
	var someone = {
		 name : 'tom',
		 showName : function(){
			 alert(this.name);
		}
	var other = {
		name : 'Bob',
		showName : someone.showName
		}
	other.showName(); //Bob
 结果显示Bob.  this关键字虽然声明在someone.showName,但运行时是在other.showName,所以this指向other对象。所以弹出的是Bob。

##没有明确的当前对象时
在没有明确的运行时对象时,this指向全局对象(global),在浏览器环境中也就是window对象。
By default, this refers to the global object.

为什么说是全局对象(the global
object),因为非浏览器情况下(例如:nodejs)中全局变量并非window对象,而就是叫“全局变量”(the global
object)。

对与this到底指向谁,只要抓准这两点(一般而言,this指向函数执行时的当前对象,当没有明确的当前对象时,this指向全局对象)就可以慢慢弄明白!

例如对于全局变量引用的函数上有:
例2:

var name = 'window';
var Tom = {
		name : 'Tom',
		showName : function(){
			alert(this.name);
		}
	}	
var method = Tom.showName;   //method全局变量
method();  //window

在执行到var method = Tom.showName;这一句的时候,showName是对一个方法的引用(而没有执行),而把这个引用又赋值给了全局变量method。也就是说method指向了方法function(){
alert(this.name);
}
的引用,而method是一个全局变量,所以this指向window对象。
如果它

但是对于局部变量来说:
例3:

var name = 'window';
var Tom = {
		name : 'Tom',
		showName : function(){
			alert(this.name);
		}
	}	
var Bob = {
	name : 'Bob',
	showName : function(){
			var f = Tom.showName;
			f();
		}
	}
	Bob.showName();

在程序执行到Bob.showName();时,showName方法的this指向Bob对象没错,也就是说

function(){
			var f = Tom.showName;
			f();
		}

方法的this指向Bob,如果在
var f = Tom.showName之前加上一句alert(this.name)

function(){
			alert(this.name);  //Bob
			var f = Tom.showName;
			f();
		}

则会弹出’Bob’。
但方法内部方法f的this并不是指向Bob,这里没有明确说明this的指向,所以f方法的this指向window,所以执行f()
结果为’window’

setTimeout、setInterval和匿名函数

在浏览器中setTimeout、setInterval和匿名函数执行时的当前对象是全局对象window,这条我们可以看成是上一条的一个特殊情况
例4:

var name = "Bob";  
var nameObj ={  
    name : "Tom",  
    showName : function(){  
        alert(this.name);  
    },  
    waitShowName : function(){  
        setTimeout(this.showName, 1000);  
    }  
};  

nameObj.waitShowName();

在程序执行到nameObj.waitShowName();这一句时,waitShowName()的this指向nameObj对象,也就是

function(){  
        setTimeout(this.showName, 1000);  
    }  

里的this指向nameObj,所以this.showName才成立,如果这里没有this,而直接写showName则报错。但setTimeout实际调用的就是showName方法,方法体为{alert(this.name)},在调用它的时候没有指定this的指向,所以this指向window。所以最终结果为‘window’。

将代码改成匿名函数可能更好理解一些:
例5:

var name = "window";  
 var nameObj ={  
     name : "Tom",  
     showName : function(){  
         alert(this.name);  
     },  
     waitShowName : function(){  
         !function(__callback){
            __callback();
        }(this.showName);  
     }  
 };  
  nameObj.waitShowName();  

在调用nameObj.waitShowName时候,我们运行了一个匿名函数,将this.showName函数作为回调函数传递进这个匿名函数,在匿名函数运行时运行回调函数,因为匿名函数的this指向window,所以当在该匿名函数中运行回调函数时,回调函数的this也指向window。
由此看来
setTimeout、可以看做一个延迟执行的
function (_callback){
_callback();
}
setInterval同理。
如上例,如果一定需要在一秒钟之后显示nameObj 对象的name属性,可以做一些调整

 var name = "window";  
 var nameObj ={  
     name : "Tom",  
     showName : function(){  
         alert(this.name);  
     },  
     waitShowName : function(){  
         var that = this;
         setTimeout(function(){
         that.showName();
		},1000);
     }  
 };  
  nameObj.waitShowName();

这样与setTimeout的this指向window并不矛盾。setTimeout执行的具体方法是function(){ that.showName() };
that指向nameObj。并不是showName方法,所以showName方法的this指向就是它的调用者that,也就是nameObj对象。这里体现了最重要的一点:方法嵌套其实很有讲究,this并不能继承到子方法里去。

new关键字

new关键字后的构造函数中的this指向用该构造函数构造出来的新对象。

function Person(_name){
	this.name = _name;
}
Person.prototype.showName = function(){
		alert(this.name);
	}
var tom = new Person('Tom');
tom.showName();  //Tom

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值