JAVASCRIPT this关键字详解
来源:互联网 发布:数据光端机 编辑:程序博客网 时间:2024/05/02 00:11
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
- 【JavaScript】this关键字详解
- JAVASCRIPT this关键字详解
- Javascript中this关键字详解
- Javascript中this关键字详解
- Javascript中this关键字详解
- Javascript中this关键字详解
- Javascript中this关键字详解
- Javascript中this关键字详解
- Javascript中this关键字详解
- Javascript中this关键字详解
- Javascript中this关键字详解
- Javascript中this关键字详解
- Javascript中this关键字详解
- Javascript中this关键字详解
- Javascript中this关键字详解
- Javascript中this关键字详解
- JavaScript中this关键字详解
- Javascript中this关键字详解
- Hiernate 升级后获取类型的改变
- 爬楼梯
- leetcode 66. Plus One
- LaTeX技巧24:LaTeX常用命令集锦
- QApplication和QCoreApplication的用法
- JAVASCRIPT this关键字详解
- jquery选择器
- Linux进程调度分析
- CSS3盒阴影box-shadow
- 标准SQL规范中定义的四个事务隔离级别
- Android学习笔记12:图像渲染(Shader)
- tomcat 多域名配置
- java找不到或无法加载主类
- error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'std::string'