JS篇——javascript中的this
2016-06-02 14:55
363 查看
一直以来貌似都还没有更新js篇,本来是打算将css3和html5更新完之后再从头总结js,最后发现开始那些好像也没啥总结的,而且我这速度还不知道何时能把css3和html5总结完,所以就想到哪就更哪了,本来今天准备更新闭包,然后发现更新闭包之前,我最好先更新下js中的this关键字,所以这一篇更新js中的this关键字。
javascript中的this
在java中,this固定指向运行时的当前对象。但在javascript中,this的含义要多的多,它可以是全局对象、当前对象或者任意对象,完全取决于函数调用的方式。
this究竟指向哪里
一句话,javascript中的this指向的是执行时的当前对象,而不是声明时的当前对象。这句话什么意思,看下面例子。
上面这个例子最后弹出的是全局变量1,虽然this是在test.show里面声明的,但是执行的时候的对象却不是test,所以this不是指向的test对象,这是为啥呢,后面再说。
Javascript一共有四种调用模式:对象方法调用模式、纯函数调用模式、构造器调用模式以及apply调用模式。调用模式不同,对应的隐藏参数this值也会不同。
对象方法调用模式
函数作为对象的属性时,称为方法。此时函数(即方法)中的this对应是该对象。
然而,还有另外一种情况的方法调用,就是“this究竟指向哪里”中的例子。
谈到这里就顺便说一下setTimeout、setInterval和匿名函数中的“this”.
在浏览器中setTimeout、setInterval和匿名函数执行时的当前对象是全局对象window,浏览器中全局变量可以当成是window对象下的变量,例如:全局变量a,可以用window.a来引用。
怎样可以让上面例子弹出2呢?
弹出2,这是因为在setTimeout中的匿名函数运行前,this指定的当前对象是test(这时运行的test对象的other属性),现将test对象赋值给that,setTimeout中的匿名函数运行后,改变的是this指定的对象,与that无关,that仍指定test对象。
这里再说一下setTimeout(函数名,延迟),setTimeout(匿名函数,延迟),setTimeout(字符串,延迟)这三的区别。以下面例子为例:
test.show()是函数运行,这种传递方式真正传进去的是test.show()函数的返回值。如果是setInterval(test.show(),1000)这种方式只会执行test.show()一次,因为test.show()已经执行了,和setTimeout、setInterval其实没有关系。
setTimeout(匿名函数,延迟)(比如setTimeout(test.show,1000))
这个相当于一个延时执行,传入了一个匿名函数,此时this变量是全局变量window,但是注意,它是没有传入函数参数的,如果函数有参数的话,建议使用闭包或者使用setTimeout(字符串,延迟)
setTimeout(字符串,延迟)比如setTimeout("test.show()",1000))
这个也相当于一个延时执行,用字符串代码创建了一个新的函数,因此该函数没有明确的对象,所以this指向全局变量。
这种很简单,此时this就代表全局对象,即window。
构造器,就是生成一个新对象,这时,这个this就指这个新对象。
这就是上面说的那种情况,纯函数调用模式,这里的this对象就是全局对象window.
这里的this对象就是new新创建的对象,新创建的对象里面并没有定义this.a,所以this.a为undefined。
apply调用模式
apply()是函数对象的一个方法,它的作用是改变函数的调用对象,它的第一个参数就表示改变后的调用这个函数的对象,因此,this指的就是这第一个参数。
call的用法和apply大致相同,只有一点区别,apply只接受两个参数,第一个参数和call相同,第二个参数必须是一个数组,数组中的元素对应的就是函数的形参。所以这里只主要讲一个apply。
javascript中的this
在java中,this固定指向运行时的当前对象。但在javascript中,this的含义要多的多,它可以是全局对象、当前对象或者任意对象,完全取决于函数调用的方式。
this究竟指向哪里
一句话,javascript中的this指向的是执行时的当前对象,而不是声明时的当前对象。这句话什么意思,看下面例子。
var x=1; var test= { x: 2, show : function(){ alert(this.x); } }; var obj = test.show; obj();//1
上面这个例子最后弹出的是全局变量1,虽然this是在test.show里面声明的,但是执行的时候的对象却不是test,所以this不是指向的test对象,这是为啥呢,后面再说。
Javascript一共有四种调用模式:对象方法调用模式、纯函数调用模式、构造器调用模式以及apply调用模式。调用模式不同,对应的隐藏参数this值也会不同。
对象方法调用模式
函数作为对象的属性时,称为方法。此时函数(即方法)中的this对应是该对象。
var x=1; var test= { x: 2, show : function(){ alert(this.x); } }; test.show();//2弹出2,此刻运行的是test对象的show属性,所以this指向test对象,所以当前对象是test对象。
然而,还有另外一种情况的方法调用,就是“this究竟指向哪里”中的例子。
var x=1; var test= { x: 2, show : function(){ alert(this.x); } }; var obj = test.show; obj();//1此时弹出的是1,此刻并不是调用了test这个对象的show属性,而是将test.show这个函数赋值给obj,又因为该函数是一个匿名函数,本身是没有对象的,所以show方法里的this就没有对象,没有对象就是window,window.x就是全局变量1。
谈到这里就顺便说一下setTimeout、setInterval和匿名函数中的“this”.
在浏览器中setTimeout、setInterval和匿名函数执行时的当前对象是全局对象window,浏览器中全局变量可以当成是window对象下的变量,例如:全局变量a,可以用window.a来引用。
var x=1; var test= { x: 2, show : function(){ alert(this.x); }, other:function(){ setTimeout(function(){ alert(this.x); }, 1000); } }; test.other();//1弹出1,这是因为setTimeout中的匿名函数运行时,匿名函数中的this指向window,所以window.x弹出1。setInterval与setTimeout类似。
怎样可以让上面例子弹出2呢?
var x=1; var test= { x: 2, show : function(){ alert(this.x); }, other:function(){ var that = this; setTimeout(function(){ alert(that.x); }, 1000); } }; test.other();//2
弹出2,这是因为在setTimeout中的匿名函数运行前,this指定的当前对象是test(这时运行的test对象的other属性),现将test对象赋值给that,setTimeout中的匿名函数运行后,改变的是this指定的对象,与that无关,that仍指定test对象。
这里再说一下setTimeout(函数名,延迟),setTimeout(匿名函数,延迟),setTimeout(字符串,延迟)这三的区别。以下面例子为例:
var x=1; var test= { x: 2, show : function(){ alert(this.x); } };setTimeout(函数名,延迟)(比如setTimeout(test.show(),1000))
test.show()是函数运行,这种传递方式真正传进去的是test.show()函数的返回值。如果是setInterval(test.show(),1000)这种方式只会执行test.show()一次,因为test.show()已经执行了,和setTimeout、setInterval其实没有关系。
setTimeout(匿名函数,延迟)(比如setTimeout(test.show,1000))
这个相当于一个延时执行,传入了一个匿名函数,此时this变量是全局变量window,但是注意,它是没有传入函数参数的,如果函数有参数的话,建议使用闭包或者使用setTimeout(字符串,延迟)
setTimeout(字符串,延迟)比如setTimeout("test.show()",1000))
这个也相当于一个延时执行,用字符串代码创建了一个新的函数,因此该函数没有明确的对象,所以this指向全局变量。
var x = 1; var obj ={ x : 2, show : function(){ alert(this.x); }, other : function(){ var that = this; setTimeout("that.show();", 1000); } }; obj.other();//报错纯函数调用模式
这种很简单,此时this就代表全局对象,即window。
function show(){ this.x = 2; alert(this.x); } show();//2
var x = 1; function show(){ alert(this.x); } show();//1
var x = 1; function show(){ this.x = 2; } show(); alert(this.x);//2构造器调用模式
构造器,就是生成一个新对象,这时,这个this就指这个新对象。
var x=1; function show(){ x=2; alert(x); alert(this.x); var x; alert(this.x); alert(x); } show();上面弹出的结果是2,1,1,2
这就是上面说的那种情况,纯函数调用模式,这里的this对象就是全局对象window.
var x=1; function show(){ x=2; alert(x); alert(this.x); var x; alert(this.x); alert(x); } var test = new show(); test();上面弹出的是2,undefined,undefined,2
这里的this对象就是new新创建的对象,新创建的对象里面并没有定义this.a,所以this.a为undefined。
apply调用模式
apply()是函数对象的一个方法,它的作用是改变函数的调用对象,它的第一个参数就表示改变后的调用这个函数的对象,因此,this指的就是这第一个参数。
call的用法和apply大致相同,只有一点区别,apply只接受两个参数,第一个参数和call相同,第二个参数必须是一个数组,数组中的元素对应的就是函数的形参。所以这里只主要讲一个apply。
var x=1; function show(a){ this.x = this.x+a; alert(this.x); } var obj = { x:0 }; show.apply();//NaN,apply()的参数为空时,默认调用全局对象,所以this.x为1,但此时show函数的参数中没有定义a,因此a为undefined,所以结果为NaN show.apply(obj,[3]);//3,此时this对象为obj对象,所以this.x为0。0+3等于3。 show.call(obj,4);//7,此时this对象是obj对象,但因为上一步,所以现在obj中的x为3,3+4等于7
相关文章推荐
- JQuery1——基础($对象,选择器,对象转换)
- Android学习笔记(二九):嵌入浏览器
- Android java 与 javascript互访(相互调用)的方法例子
- GUI - Web前端开发框架
- JavaScript演示排序算法
- javascript实现10进制转为N进制数
- 最后一次说说闭包
- Ajax
- 2019年开发人员应该学习的8个JavaScript框架
- HTML中的script标签研究
- 对一个分号引发的错误研究
- 异步流程控制:7 行代码学会 co 模块
- ES6 走马观花(ECMAScript2015 新特性)
- JavaScript拆分字符串时产生空字符的原因
- Canvas 在高清屏下绘制图片变模糊的解决方法
- Redux系列02:一个炒鸡简单的react+redux例子
- JavaScript 各种遍历方式详解