js中this的理解

关于this

  • this并不是指向函数本身。
  • this在任何情况下都不指向函数的词法作用域。
  • this是在运行时进行绑定的,而并不是在编写时绑定,它的上下文取决于函数调用时的各种条件。
  • this的绑定和函数声明的位置没有任何关系,只取决与函数的调用方法。

this的绑定规则

this到底绑定或者引用的是哪个对象环境决定于函数被调用的地方。而函数的调用有不同的方式,在不同的方式中调用决定this引用的是哪个对象是由四种规则确定的。

1、默认绑定

这条规则是最常见的,也是默认的。当函数被单独定义和调用的时候,应用的规则就是绑定全局变量window(严格模式下是undefined)。即没有其他绑定规则存在时的默认规则。

function fn() {
    console.log( this.a );
}
var a = 2;
fn(); // 2 -- fn单独调用,this引用window

 

为什么说这里应用了默认绑定呢?

因为fn()是直接使用不带任何修饰的函数引用进行调用的,因此只能使用默认绑定,无法应用其他规则。

2、隐式绑定

隐式调用的意思是,函数调用时拥有一个上下文对象,就好像这个函数是属于该对象的一样。必须在一个对象内部包含一个指向函数的属性,并通过这个属性间接引用函数,从而把this间接(隐式)绑定到这个对象上。

function fn() {
    console.log( this.a );
}
var obj = {
    a: 2,
    fn: fn
};
obj.fn(); // 2 -- this引用obj。

当函数引用有上下文对象时,隐式绑定规则会把函数调用中的this绑定到这个上下文对象。

需要说明的一点是,最后一个调用该函数的对象是传到函数的上下文对象,对象属性引用链中只有上一层或者说最后一层在调用位置中起作用,如下:

 function fn() {
     console.log( this.a );
 }
 var obj2 = {
     a: 42,
     fn: fn
 };
 var obj1 = {
     a: 2,
     obj2: obj2
 };
 obj1.obj2.fn(); // 42 -- this引用的是obj2.

如果一个函数中有this,这个函数中包含多个对象,尽管这个函数是被最外层的对象所调用,this指向的也只是它上一级的对象

隐式丢失问题:被隐式绑定的函数会丢失绑定对象,也就是说它会默认绑定,从而把this绑定到全局对象或undefined上,取决于是否是严格模式。如下:

 function fn() {
     console.log( this.a );
 }
 var obj = {
     a: 2,
     fn: fn
 };
 var bar = obj.fn; // 函数引用传递,只是函数的别名,而不是调用这个函数
 var a = "全局"; // 定义全局变量
 bar(); // "全局"

3、显式绑定

使用bind()\apply()\call()函数:它接收的第一个参数即是上下文对象并将其赋给this

 function fn() {
     console.log( this.a );
 }
 var obj = {
     a: 2
 };
 fn.call( obj ); // 2

如果我们传递第一个值为简单值,那么后台会自动转换为对应的封装对象。如果传递为null,那么结果就是在绑定默认全局变量,如:

 function fn() {
      console.log( this.a );
  }
  var obj = {
      a: 2
  };
 var a = 10;
 fn.call( null); // 10

4、new绑定

如果是一个构造函数,那么用new来调用,那么绑定的是新创建的对象,如下:

function fn(a) {
    this.a = a;
}
var bar = new fn( 2 );
console.log( bar.a );// 2

当this碰到return时

如下代码:

function fn()  
{  
    this.user = '追梦子';  
    return {};  
}
var a = new fn;  
console.log(a.user); //undefined
function fn()  
{  
    this.user = '追梦子';  
    return function(){};
}
var a = new fn;  
console.log(a.user); //undefined

再如:

function fn()  
{  
    this.user = '追梦子';  
    return 1;
}
var a = new fn;  
console.log(a.user); //追梦子
function fn()  
{  
    this.user = '追梦子';  
    return undefined;
}
var a = new fn;  
console.log(a.user); //追梦子

总结:

  • 如果返回值是一个对象,那么this指向的就是那个返回的对象,如果返回值不是一个对象那么this还是指向函数的实例。
  • 还有一点就是虽然null也是对象,但是在这里this还是指向那个函数的实例,因为null比较特殊。
    function fn()  
    {  
        this.user = '追梦子';  
        return null;
    }
    var a = new fn;  
    console.log(a.user); //追梦子

 

posted @ 2018-08-02 17:46  L_mj  阅读(2031)  评论(0编辑  收藏  举报