JavaScript之this指针深入详解

javascript中的this含义非常丰富,它可以是全局对象,当前对象或者是任意对象,这都取决于函数的调用方式。函数有以下几种调用方式:作为对象方法调用、作为函数调用、作为构造函数调用、apply或call调用。

致力于企业形象建设和产品!多年来,创新互联公司不忘初心,以建立行业服务标杆为目标,不断提升技术设计服务水平,帮助客户在互联网推广自己的产品、服务,为客户创造价值从而实现自身价值!中小型企业如何做成都品牌网站建设?初创业公司建站预算不足?

对象方法调用

作为对象方法调用的时候,this会被绑定到该对象。

 
 
  1. var point = {
  2. x : 0,
  3. y : 0,
  4. moveTo : function(x, y) {
  5.      this.x = this.x + x;
  6.      this.y = this.y + y;
  7.      }
  8. };

point.moveTo(1, 1)//this 绑定到当前对象,即 point 对象

这里我想强调一点内容,就是this是在函数执行的时候去获取对应的值,而不是函数定义时。即使是对象方法调用,如果该方法的函数属性以函数名的形式传入别的作用域,也会改变this的指向。我举一个例子:

 
 
  1. var a = {
  2. aa : 0,
  3. bb : 0,
  4. fun : function(x,y){
  5.   this.aa = this.aa + x;
  6.   this.bb = this.bb + y;
  7. }
  8. };
  9. var aa = 1;
  10. var b = {
  11. aa:0,
  12. bb:0,
  13. fun : function(){return this.aa;}
  14. }
  15. a.fun(3,2);
  16. document.write(a.aa);//3,this指向对象本身
  17. document.write(b.fun());//0,this指向对象本身
  18. (function(aa){//注意传入的是函数,而不是函数执行的结果
  19. var c = aa();
  20. document.write(c);//1 , 由于fun在该处执行,导致this不再指向对象本身,而是这里的window
  21. })(b.fun);

这样就明白了吧。这是一个容易混淆的地方。

函数调用

函数也可以直接被调用,这个时候this被绑定到了全局对象。

 
 
  1. var x = 1;
  2.  function test(){
  3.    this.x = 0;
  4.  }
  5.  test();
  6.  alert(x); //0

但这样就会出现一些问题,就是在函数内部定义的函数,其this也会指向全局,而和我们希望的恰恰相反。代码如下:

 
 
  1. var point = {
  2. x : 0,
  3. y : 0,
  4. moveTo : function(x, y) {
  5.      // 内部函数
  6.      var moveX = function(x) {
  7.      this.x = x;//this 绑定到了全局
  8.     };
  9.     // 内部函数
  10.     var moveY = function(y) {
  11.     this.y = y;//this 绑定到了全局
  12.     };
  13.     moveX(x);
  14.     moveY(y);
  15.     }
  16. };
  17. point.moveTo(1, 1);
  18. point.x; //==>0
  19. point.y; //==>0
  20. x; //==>1
  21. y; //==>1

我们会发现不但我们希望的移动呢效果没有完成,反而会多出两个全局变量。那么如何解决呢?只要要进入函数中的函数时将this保存到一个变量中,再运用该变量即可。代码如下:

 
 
  1. var point = {
  2. x : 0,
  3. y : 0,
  4. moveTo : function(x, y) {
  5.       var that = this;
  6.      // 内部函数
  7.      var moveX = function(x) {
  8.      that.x = x;
  9.      };
  10.      // 内部函数
  11.      var moveY = function(y) {
  12.      that.y = y;
  13.      }
  14.      moveX(x);
  15.      moveY(y);
  16.      }
  17. };
  18. point.moveTo(1, 1);
  19. point.x; //==>1
  20. point.y; //==>1

构造函数调用

在javascript中自己创建构造函数时可以利用this来指向新创建的对象上。这样就可以避免函数中的this指向全局了。

  
 
  1. var x = 2;
  2.   function test(){
  3.     this.x = 1;
  4.   }
  5.   var o = new test();
  6.   alert(x); //2

apply或call调用

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

  
 
  1. var name = "window";
  2. var someone = {
  3.     name: "Bob",
  4.     showName: function(){
  5.         alert(this.name);
  6.     }
  7. };
  8. var other = {
  9.     name: "Tom"
  10. };  
  11. someone.showName();  //Bob
  12. someone.showName.apply();    //window
  13. someone.showName.apply(other);    //Tom

可以看到,正常访问对象中方法时,this指向对象。使用了apply后,apply无参数时,this的当前对象是全局,apply有参数时,this的当前对象就是该参数。

箭头函数调用

这里需要补充一点内容,就是在下一代javascript标准ES6中的箭头函数的 this始终指向函数定义时的 this,而非执行时。我们通过一个例子来理解:

  
 
  1. var o = {
  2.     x : 1,
  3.     func : function() { console.log(this.x) },
  4.     test : function() {
  5.         setTimeout(function() {
  6.             this.func();
  7.         }, 100);
  8.     }
  9. };
  10. o.test(); // TypeError : this.func is not a function

上面的代码会出现错误,因为this的指向从o变为了全局。我们需要修改上面的代码如下:

  
 
  1. var o = {
  2.     x : 1,
  3.     func : function() { console.log(this.x) },
  4.     test : function() {
  5.         var _this = this;
  6.         setTimeout(function() {
  7.             _this.func();
  8.         }, 100);
  9.     }
  10. };
  11. o.test();

通过使用外部事先保存的this就行了。这里就可以利用到箭头函数了,我们刚才说过,箭头函数的 this始终指向函数定义时的 this,而非执行时。所以我们将上面的代码修改如下:

  
 
  1. var o = {
  2.     x : 1,
  3.     func : function() { console.log(this.x) },
  4.     test : function() {
  5.         setTimeout(() => { this.func() }, 100);
  6.     }
  7. };
  8. o.test();

这回this就指向o了,我们还需要注意一点的就是这个this是不会改变指向对象的,我们知道call和apply可以改变this的指向,但是在箭头函数中是无效的。

  
 
  1. var x = 1,
  2.     o = {
  3.         x : 10,
  4.         test : () => this.x
  5.     };
  6. o.test(); // 1
  7. o.test.call(o); // 依然是1

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


 

分享题目:JavaScript之this指针深入详解
文章转载:http://www.gawzjz.com/qtweb/news21/206171.html

网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联