javascript中this用法实例详解


Posted in Javascript onApril 06, 2017

本文实例讲述了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); //0

但这样就会出现一些问题,就是在函数内部定义的函数,其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); //2

apply或call调用

这两个方法可以切换函数执行的上下文环境,也就是改变this绑定的对象。apply和call比较类似,区别在于传入参数时一个要求是数组,一个要求是分开传入。所以我们以apply为例:

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(); // 1
o.test.call(o); // 依然是1

这样就可以明白各种情况下this绑定对象的区别了。

更多关于JavaScript相关内容可查看本站专题:《javascript面向对象入门教程》、《JavaScript中json操作技巧总结》、《JavaScript切换特效与技巧总结》、《JavaScript查找算法技巧总结》、《JavaScript动画特效与技巧汇总》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript遍历算法与技巧总结》及《JavaScript数学运算用法总结》

希望本文所述对大家JavaScript程序设计有所帮助。

Javascript 相关文章推荐
js获取某月的最后一天日期的简单实例
Jun 22 Javascript
Javascript中获取对象的原型对象的方法小结
Feb 25 Javascript
javascript结合canvas实现图片旋转效果
May 03 Javascript
jQuery实现横向带缓冲的水平运动效果(附demo源码下载)
Jan 29 Javascript
js获取新浪天气接口的实现代码
Jun 06 Javascript
JS正则表达式判断有效数实例代码
Mar 13 Javascript
Angular.Js中ng-include指令的使用与实现
May 07 Javascript
JavaScript之DOM_动力节点Java学院整理
Jul 03 Javascript
如何给element添加一个抽屉组件的方法步骤
Jul 14 Javascript
jQuery设置下拉框显示与隐藏效果的方法分析
Sep 15 jQuery
解决ele ui 表格表头太长问题的实现
Nov 13 Javascript
vue中重定向redirect:‘/index‘,不显示问题、跳转出错的完美解决
Sep 28 Javascript
selenium 与 chrome 进行qq登录并发邮件操作实例详解
Apr 06 #Javascript
js遍历获取表格内数据的方法(必看)
Apr 06 #Javascript
JS优化与惰性载入函数实例分析
Apr 06 #Javascript
大白话讲解JavaScript的Promise
Apr 06 #Javascript
JS实现的二叉树算法完整实例
Apr 06 #Javascript
JavaScript结合HTML DOM实现联动菜单
Apr 05 #Javascript
js实现按座位号抽奖
Apr 05 #Javascript
You might like
PHP syntax error, unexpected $end 错误的一种原因及解决
2008/10/25 PHP
PHP 第一节 php简介
2012/04/28 PHP
PHP中iconv函数转码时截断字符问题的解决方法
2015/01/21 PHP
PHP的Socket通信之UDP通信实例
2015/07/02 PHP
php版微信公众账号第三方管理工具开发简明教程
2016/09/23 PHP
JavaScript Array扩展实现代码
2009/10/14 Javascript
jquery 清空file域示例(兼容个浏览器)
2013/10/11 Javascript
javascript 处理null及null值示例
2014/06/09 Javascript
上传文件返回的json数据会被提示下载问题解决方案
2014/12/03 Javascript
Jquery树插件zTree用法入门教程
2015/02/17 Javascript
JavaScript直播评论发弹幕切图功能点集合效果代码
2016/06/26 Javascript
Angular ng-repeat 对象和数组遍历实例
2016/09/14 Javascript
Bootstrap CSS组件之下拉菜单(dropdown)
2016/12/17 Javascript
ES6中Math对象的部分扩展
2017/02/20 Javascript
关于jquery form表单序列化的注意事项详解
2017/08/01 jQuery
Vue中使用ElementUI使用第三方图标库iconfont的示例
2018/10/11 Javascript
Node.js如何优雅的封装一个实用函数的npm包的方法
2019/04/29 Javascript
解决ie11 SCRIPT5011:不能执行已释放Script的代码问题
2019/05/05 Javascript
vue下使用nginx刷新页面404的问题解决
2019/08/02 Javascript
Node.js API详解之 timer模块用法实例分析
2020/05/07 Javascript
原生jQuery实现只显示年份下拉框
2020/12/24 jQuery
vue浏览器返回监听的具体步骤
2021/02/03 Vue.js
利用ctypes提高Python的执行速度
2016/09/09 Python
Rowdy Gentleman服装和配饰:美好时光
2019/09/24 全球购物
SOA面试题:如何在SOA中实现松耦合
2013/07/21 面试题
销售类个人求职信范文
2013/09/25 职场文书
办公室文员工作职责
2014/01/31 职场文书
施工安全责任书
2014/04/14 职场文书
2014国庆65周年领导讲话稿(3篇)
2014/09/21 职场文书
爱岗敬业事迹材料
2014/12/24 职场文书
2015年员工工作表现评语
2015/03/25 职场文书
小学英语教学经验交流材料
2015/11/02 职场文书
小学生法制教育心得体会
2016/01/14 职场文书
《槐乡的孩子》教学反思
2016/02/20 职场文书
关于python中readlines函数的参数hint的相关知识总结
2021/06/24 Python
C3 线性化算法与 MRO之Python中的多继承
2021/10/05 Python