JavaScript之this指针深入详解
javascript中的this含义非常丰富,它可以是全局对象,当前对象或者是任意对象,这都取决于函数的调用方式。函数有以下几种调用方式:作为对象方法调用、作为函数调用、作为构造函数调用、apply或call调用。
对象方法调用
作为对象方法调用的时候,this会被绑定到该对象。
var point = { x : 0, y : 0, moveTo : function(x, y) { this.x = this.x + x; this.y = this.y + y; } }; point.moveTo(1, 1)//this 绑定到当前对象,即 point 对象
这里我想强调一点内容,就是this是在函数执行的时候去获取对应的值,而不是函数定义时。即使是对象方法调用,如果该方法的函数属性以函数名的形式传入别的作用域,也会改变this的指向。我举一个例子:
var a = { aa : 0, bb : 0, fun : function(x,y){ this.aa = this.aa + x; this.bb = this.bb + y; } }; var aa = 1; var b = { aa:0, bb:0, fun : function(){return this.aa;} } a.fun(3,2); document.write(a.aa);//3,this指向对象本身 document.write(b.fun());//0,this指向对象本身 (function(aa){//注意传入的是函数,而不是函数执行的结果 var c = aa(); document.write(c);//1 , 由于fun在该处执行,导致this不再指向对象本身,而是这里的window })(b.fun);
这样就明白了吧。这是一个容易混淆的地方。
函数调用
函数也可以直接被调用,这个时候this被绑定到了全局对象。
var x = 1; function test(){ this.x = 0; } test(); alert(x);
但这样就会出现一些问题,就是在函数内部定义的函数,其this也会指向全局,而和我们希望的恰恰相反。代码如下:
var point = { x : 0, y : 0, moveTo : function(x, y) { // 内部函数 var moveX = function(x) { this.x = x;//this 绑定到了全局 }; // 内部函数 var moveY = function(y) { this.y = y;//this 绑定到了全局 }; moveX(x); moveY(y); } }; point.moveTo(1, 1); point.x; //==>0 point.y; //==>0 x; //==>1 y; //==>1
我们会发现不但我们希望的移动呢效果没有完成,反而会多出两个全局变量。那么如何解决呢?只要要进入函数中的函数时将this保存到一个变量中,再运用该变量即可。代码如下:
var point = { x : 0, y : 0, moveTo : function(x, y) { var that = this; // 内部函数 var moveX = function(x) { that.x = x; }; // 内部函数 var moveY = function(y) { that.y = y; } moveX(x); moveY(y); } }; point.moveTo(1, 1); point.x; //==>1 point.y; //==>1
构造函数调用
在javascript中自己创建构造函数时可以利用this来指向新创建的对象上。这样就可以避免函数中的this指向全局了。
var x = 2; function test(){ this.x = 1; } var o = new test(); alert(x);
apply或call调用
这两个方法可以切换函数执行的上下文环境,也就是改变this绑定的对象。apply和call比较类似,区别在于传入参数时一个要求是数组,一个要求是分开传入。所以我们以apply为例:
<pre name="code" class="html">var name = "window"; var someone = { name: "Bob", showName: function(){ alert(this.name); } }; var other = { name: "Tom" }; someone.showName(); //Bob someone.showName.apply(); //window someone.showName.apply(other); //Tom
可以看到,正常访问对象中方法时,this指向对象。使用了apply后,apply无参数时,this的当前对象是全局,apply有参数时,this的当前对象就是该参数。
箭头函数调用
这里需要补充一点内容,就是在下一代javascript标准ES6中的箭头函数的 this始终指向函数定义时的 this,而非执行时。我们通过一个例子来理解:
var o = { x : 1, func : function() { console.log(this.x) }, test : function() { setTimeout(function() { this.func(); }, 100); } }; o.test(); // TypeError : this.func is not a function
上面的代码会出现错误,因为this的指向从o变为了全局。我们需要修改上面的代码如下:
var o = { x : 1, func : function() { console.log(this.x) }, test : function() { var _this = this; setTimeout(function() { _this.func(); }, 100); } }; o.test();
通过使用外部事先保存的this就行了。这里就可以利用到箭头函数了,我们刚才说过,箭头函数的 this始终指向函数定义时的 this,而非执行时。所以我们将上面的代码修改如下:
var o = { x : 1, func : function() { console.log(this.x) }, test : function() { setTimeout(() => { this.func() }, 100); } }; o.test();
这回this就指向o了,我们还需要注意一点的就是这个this是不会改变指向对象的,我们知道call和apply可以改变this的指向,但是在箭头函数中是无效的。
var x = 1, o = { x : 10, test : () => this.x }; o.test(); o.test.call(o); // 依然是1
这样就可以明白各种情况下this绑定对象的区别了。
JavaScript之this指针深入详解的更多相关文章
- javascript常用经典算法实例详解
javascript常用经典算法实例详解 这篇文章主要介绍了javascript常用算法,结合实例形式较为详细的分析总结了JavaScript中常见的各种排序算法以及堆.栈.链表等数据结构的相关实现与 ...
- javascript中=、==、===区别详解
javascript中=.==.===区别详解今天在项目开发过中发现在一个小问题.在判断n==""结果当n=0时 n==""结果也返回了true.虽然是个小问题 ...
- Javascript 调试利器 Firebug使用详解
Javascript 调试利器 Firebug使用详解 有时候,为了更清楚方便的查看输出信息,我们可能需要将一些调试信息进行分组输出,那么可以使用console.group来对信息进行分组,在组信息输 ...
- JavaScript中return的用法详解
JavaScript中return的用法详解 最近,跟身边学前端的朋友了解,有很多人对函数中的this的用法和指向问题比较模糊,这里写一篇博客跟大家一起探讨一下this的用法和指向性问题. 1定义 t ...
- javascript 中合并排序算法 详解
javascript 中合并排序算法 详解 我会通过程序的执行过程来给大家合并排序是如何排序的... 合并排序代码如下: <script type="text/javascript& ...
- javascript中的this作用域详解
javascript中的this作用域详解 Javascript中this的指向一直是困扰我很久的问题,在使用中出错的机率也非常大.在面向对象语言中,它代表了当前对象的一个引用,而在js中却经常让我觉 ...
- JavaScript中this的用法详解
JavaScript中this的用法详解 最近,跟身边学前端的朋友了解,有很多人对函数中的this的用法和指向问题比较模糊,这里写一篇博客跟大家一起探讨一下this的用法和指向性问题. 1定义 thi ...
- 高性能JavaScript模板引擎实现原理详解
这篇文章主要介绍了JavaScript模板引擎实现原理详解,本文着重讲解artTemplate模板的实现原理,它采用预编译方式让性能有了质的飞跃,是其它知名模板引擎的25.32 倍,需要的朋友可以参考 ...
- JavaScript对象的property属性详解
JavaScript对象的property属性详解:https://www.jb51.net/article/48594.htm JS原型与原型链终极详解_proto_.prototype及const ...
随机推荐
- iOS设备、Icon、LaunchImage、图片分辨率
iOS设备 iOS设备的屏幕的大小.分辨率以及比例因数(Scale Factor)[1]. iPhone 设备 宽(inch) 高(inch) 对角线(inch) 逻辑分辨率(point) Scale ...
- struts2 测试错题解析
解析:$.parseJSON()方法是将字符串转换成Json类型数据,$.getJSON()方法是获取JSON数据,两者不用联合使用. 解析: A:ActionContext接口没有getReques ...
- Git命令详解【2】
git的工作区 git 安装 sudo apt-get insall git 查看git 版本 git --version git的配置 #配置用户名 git config --global ...
- STP根交换机,指定端口,根端口,阻塞端口
STP判断各交换机端口(指定端口:DP;根端口:RP;阻塞端口:AP) 判断步骤: 1.选举根交换机: 判断对象:所有运行STP协议的交换机中选出一个; 判断依据:交换机中选择网桥ID值(交换机优先级 ...
- 手机定位原理 - GPS/GLONASS/北斗 + WIFI + 基站
卫星定位系统 - GPS/GLONASS/北斗: 关于GPS.GLONASS.北斗.伽利略系统的科普请自行谷歌. GPS是使用最广泛的全球定位网络,几乎是所有智能手机的标配.进几年,俄罗斯的GLONA ...
- sec:authorize 标签 通过不通过权限例子
1. 方式一 <sec:authorize ifAnyGranted="ROLE_A"> <a href="a.jsp"> ...
- JavaScript学习总结【9】、DOM Ready
1.DOM DOM(Document Object Model)即文档对象模型,是从文档中抽象出来的,DOM 操作的对象就是文档,DOM 将 HTML 文档呈现为带有元素.属性和文本的树结构,即节点树 ...
- runas /user:administrator cmd 以管理员身份运行CMD
runas /user:administrator cmd 以管理员身份运行CMD 1.windows+r打开 2.然后根据提示输入密码
- js更新页面,随机更新数字
代码1: <script> function getRandom(){ var i = Math.random()*40+160; document.getElementById(&quo ...
- ubuntu 选择最快得源
root权限.新版的Ubuntu(12.04)已经不再自带类似apt-spy之类的选择最快的源的命令行工具,默认的源经常那个龟速啊……手动测试哪个源在当前网络环境下会比较快还是比较累的,这里整理一个脚 ...