javascript中this的指向问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了javascript中this的指向问题相关的知识,希望对你有一定的参考价值。

想学好javascript不是一件容易的事,而this就是其中一道坎,尤其是在用js进行面向对象开发的时候。

实际上,想要彻底搞懂this的指向确实不是一件容易的事,在《你不知道的javascript 上卷》一书中更是花了很大篇幅详细总结了this的四种指向情景。我在艰难的啃完这本书和大量阅读《javascript高级程序设计》、博文、以及大量实践中终于是弄懂了this。确实是,有些知识是需要反复验证、理解、总结,直至豁然开朗,构建成属于自己的理论体系。

那么进入正文:

javascript中的this一般可以分为四种情况:

  1. 函数调用;
  2. 方法调用;
  3. 构造器调用;
  4. 间接调用。

1.函数调用

在非严格模式下,函数调用时,函数内部的this会默认指向window。

function fn(){
  console.log(this);
}
fn();//函数调用 this --> window

2.方法调用

方法调用就是,一个函数被定义为一个对象的属性(方法),并且以[对象].[方法]()的形式被调用,函数内部的this指向[对象]本身。

例如:

var obj={
    fn:function(){
console.log(this);
} }
obj.fn();//方法调用 this --> obj

有些情况下,可能会将函数调用误认为是方法调用。

例如:

var obj={
    fn:function(){
    console.log(this);
  } };
function foo(callback){
        callback();
}
foo(obj.fn);//点击触发时,打印:window

可能会有人对上面代码的结果产生困惑,实际上作为回调函数的函数属于函数调用。obj.fn并不是方法调用,而是存储了一个函数的地址,并成为了一个实参。

3.构造器调用

所谓构造器调用,就是当函数与new关键字配合创建实例时,函数内部的this在会指向新创建的实例。

例如:

function Person(name){
  this.name=name;
}
var p=new Person(‘Bob‘);//构造器调用 函数执行时this --> p
console.log(p.name);//‘Bob‘

4.间接调用

这种函数调用方式需要借助两个方法:call()或者apply()。

语法:[函数].call(obj,arg1,arg2,...)或者[函数].apply(obj,[arguments])

通过一个函数来调用call()或者apply()时,函数中的this被明确的规定指向第一个参数obj,这种方式常常用于对其他对象方法的借用。

例如:

var obj1={
  name:‘小明‘,
  say:function(){
    console.log(this.name);
  }
};
var obj2={
  name:‘小红‘
};
obj1.say();//方法调用 this --> obj1 打印结果:小明
obj1.say.call(obj2);//间接调用 this --> obj2 打印结果:小红

其次,还有一个方法bind()也可以将函数的this强制指向某一个对象。

语法:[函数].bind(obj)

返回值:函数的副本,该副本中的this将永远指向obj

bind()方法与call()、apply()的区别就是:bind()不会立即执行函数,而是返回一个函数的副本。

具体的作用请戳  强大的bind方法

其实还有一种很特殊的情况:

函数作为事件的回调函数,函数内部的this指向事件绑定的对象。





















以上是关于javascript中this的指向问题的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript中this的指向问题

关于 JavaScript 中 this 指向的理解

JavaScript-改变this指向

setTimeout中所执行函数中的this,永远指向window

JavaScript中this指向问题

JavaScript严格模式下this指向