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 相关文章推荐
深入document.write()与HTML4.01的非成对标签的详解
May 08 Javascript
js脚本获取webform服务器控件的方法
May 16 Javascript
JQuery日历插件My97DatePicker日期范围限制
Jan 20 Javascript
JS使用正则表达式实现关键字替换加粗功能示例
Aug 03 Javascript
jQuery 如何实现一个滑动按钮开关
Dec 01 Javascript
Angular.js实现获取验证码倒计时60秒按钮的简单方法
Oct 18 Javascript
详解express + mock让前后台并行开发
Jun 06 Javascript
webpack+vue-cli项目中引入外部非模块格式js的方法
Sep 28 Javascript
详解react-refetch的使用小例子
Feb 15 Javascript
ES6知识点整理之函数对象参数默认值及其解构应用示例
Apr 17 Javascript
如何在微信小程序中存setStorage
Dec 13 Javascript
浅谈VUE中演示v-for为什么要加key
Jan 16 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实现单例模式最安全的做法
2014/06/13 PHP
Windows Server 2008 R2和2012中PHP连接MySQL过慢的解决方法
2016/07/02 PHP
PHP水印类,支持添加图片、文字、填充颜色区域的实现
2017/02/04 PHP
PHP array_reduce()函数的应用解析
2018/10/28 PHP
javascript 播放器 控制
2007/01/22 Javascript
增强的 JavaScript 的 trim 函数的代码
2007/08/13 Javascript
javascript 随机展示头像实现代码
2011/12/06 Javascript
javascript/jquery获取地址栏url参数的方法
2014/03/05 Javascript
JavaScript学习笔记之JS事件对象
2015/01/22 Javascript
jQuery xml字符串的解析、读取及查找方法
2016/03/01 Javascript
javascript关于继承解析
2016/05/10 Javascript
js鼠标单击和双击事件冲突问题的快速解决方法
2016/07/11 Javascript
AngularJS基础 ng-submit 指令简单示例
2016/08/03 Javascript
js构建二叉树进行数值数组的去重与优化详解
2018/03/26 Javascript
利用jquery和BootStrap实现动态滚动条效果
2018/12/03 jQuery
vue路由切换之淡入淡出的简单实现
2019/10/31 Javascript
微信小程序实现滚动加载更多的代码
2019/12/06 Javascript
[54:54]Newbee vs Serenity 2018国际邀请赛小组赛BO2 第一场 8.17
2018/08/18 DOTA
Python使用Tkinter实现机器人走迷宫
2018/01/22 Python
python生成requirements.txt的两种方法
2019/09/18 Python
Python3如何对urllib和urllib2进行重构
2019/11/25 Python
解决python中import文件夹下面py文件报错问题
2020/06/01 Python
Matplotlib.pyplot 三维绘图的实现示例
2020/07/28 Python
html5画布旋转效果示例
2014/01/27 HTML / CSS
俄罗斯园林植物网上商店:Garshinka
2020/07/16 全球购物
工商管理本科毕业生求职信范文
2013/10/05 职场文书
会计专业自荐信
2013/12/02 职场文书
简单而又朴实的个人求职信分享
2013/12/12 职场文书
社团活动策划书范文
2014/01/09 职场文书
《赵州桥》教学反思
2014/02/17 职场文书
《寓言两则》教学反思
2014/02/27 职场文书
大学生社会实践评语
2014/04/25 职场文书
学习十八大标语
2014/10/09 职场文书
Win11怎么把合并的任务栏分开 Win11任务栏合并分开教程
2022/04/06 数码科技
gtx1650怎么样 gtx1650显卡相当于什么级别
2022/04/08 数码科技
python如何将mat文件转为png
2022/07/15 Python