this的指向

分4种:

  1. 作为对象的方法调用
  2. 作为普通函数调用
  3. 构造器调用
  4. Function.prototype.call或Function.prototype.apply调用

1、作为对象的方法调用

当函数作为对象的方法被调用时,this 指向该对象:
var obj = { 
 a: 1, 
 getA: function(){ 
 alert ( this === obj ); // 输出:true 
 alert ( this.a ); // 输出: 1 
 } 
}; 
obj.getA();

2、作为普通函数调用

当函数不作为对象的属性被调用时,也就是我们常说的普通函数方式,此时的 this 总是指 向全局对象。在浏览器的 JavaScript 里,这个全局对象是 window 对象。
 

window.name = 'globalName'; 
var myObject2 = { 
 name: 'sven', 
 getName: function(){ 
 return this.name; 
 } 
}; 
var getName = myObject2.getName; 
console.log( getName() ); // globalName 不作为对象的属性,则this指向全局对象window
console.log(myObject2.getName()) // sven 作为对象的属性被调用时,则this指向对象

有时候我们会遇到一些困扰,比如在 div 节点的事件函数内部,有一个局部的 callback 方法, callback 被作为普通函数调用时,callback 内部的 this 指向了 window,但我们往往是想让它指向 该 div 节点,见如下代码:
 

<html> 
 <body> 
 <div id="div1">我是一个 div</div> 
 </body> 
 <script> 
 window.id = 'window'; 
 document.getElementById( 'div1' ).onclick = function(){ 
     alert ( this.id ); // 输出:'div1' 
     var callback = function(){ 
             alert ( this.id ); // 输出:'window' 
      } 
     callback(); 
 }; 
 </script> 
</html> 
此时有一种简单的解决方案,可以用一个变量保存 div 节点的引用:
document.getElementById( 'div1' ).onclick = function(){ 
   var that = this; // 保存 div 的引用
   var callback = function(){ 
      alert ( that.id ); // 输出:'div1' 
   } 
   callback(); 
}; 
在 ECMAScript 5 的 strict 模式下,这种情况下的 this 已经被规定为不会指向全局对象,而
是 undefined:
function func(){ 
   "use strict" 
   alert ( this ); // 输出:undefined 
} 
func();

3、构造器调用

Es5之前没有类,但可以从构造器中创建对象,同时提供了new运算符,看起来像类。在构造器中this指向返回的这个对象。

var MyClass = function(){ 
 this.name = 'sven';  
}; 
var obj = new MyClass(); 
alert ( obj.name ); // 输出:sven 因为this指向Obj这个返回的对象

但用 new 调用构造器时,还要注意一个问题,如果构造器显式地返回了一个 object 类型的对 象,那么此次运算结果最终会返回这个对象,而不是我们之前期待的 this:

var MyClass = function(){ 
 this.name = 'sven'; 
 return { // 显式地返回一个对象
 name: 'anne' 
 } 
}; 
var obj = new MyClass(); 
alert ( obj.name ); // 输出:anne

如果构造器不显式地返回任何数据,或者是返回一个非对象类型的数据,就不会造成上述 问题:

var MyClass = function(){ 
 this.name = 'sven' 
 return 'anne'; // 返回 string 类型
}; 
var obj = new MyClass(); 
alert ( obj.name ); // 输出:sven 

4、Function.prototype.call或Function.prototype.apply调用

跟普通的函数调用相比,用 Function.prototype.call 或 Function.prototype.apply 可以动态地 改变传入函数的 this:

var obj1 = { 
 name: 'sven', 
 getName: function(){ 
 return this.name; 
 } 
}; 
var obj2 = { 
 name: 'anne' 
}; 
console.log( obj1.getName() ); // 输出: sven 
console.log( obj1.getName.call( obj2 ) ); // 输出:anne

补充:this与call、apply

1、call和apply的区别:传参个数不同

call(指定函数体内this对象的指向,参数1,参数2...)

apply(指定函数体内this对象的指向,参数数组[xx,xx,xx...])

apply更高的使用频率。

2、call和apply的用途:改变this指向

假如该事件函数中有一个内部函数 func,在事件内部调用 func 函数时,func 函数体内的 this 就指向了 window,而不是我们预期的 div,见如下代码:

document.getElementById( 'div1' ).onclick = function(){ 
   alert( this.id ); // 输出:div1 
   var func = function(){ 
      alert ( this.id ); // 输出:undefined 
   } 
   func(); 
}; 
这时候我们用 call 来修正 func 函数内的 this,使其依然指向 div:
document.getElementById( 'div1' ).onclick = function(){ 
   var func = function(){ 
     alert ( this.id ); // 输出:div1 
   } 
   func.call( this );  // 则会把当前div1传进去作为this的指向
};

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大小小丹

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值