javascript中this详解(史上最简单易理解的讲解,包你不再找错this指向)

学习js已经一年多,对this也算是了解。前两天看了一些关于this指向的面试题,打算总结一下在js中关于this 的各种问题,结果发现讲解this的博客很多,但质量高的很少,所以写下了这篇博客希望可以帮助到需要的人。

一.this指向判断

上面这张图很好的说明了this的指向问题,图中dot(.)意思就是使用对象名加方法调用,dot之前的对象就是指调用这个对象,例如下面例子中的np.x,dot之前的对象指的就是np,来看下面的例子:

1.

function gzb(x,y){  

    this.x = x; 

    this.y = y; 

 } 

var np=new gzb(1,1); 

np.x;    //1 

var p=gzb(2,2); 

p.x;    //error, p是一个空对象undefined 

x;     //2

在这个例子中,我们首先定义了一个构造函数gzb,然后使用new创建了一个对象np,从上面的图中我们可知,构造函数中的this指向创建的新对象np,所以np.x被赋值为1。然后我们又执行了var p=gzb(2,2),这行代码和var p=new gzb(2,2)的区别是什么呢?我们首先来看this指向,根据上面的图我们可知,this应该指向window,因为他既没有用new,也没有用dot(.)来进行调用。var p=gzb(2,2)的作用相当于先执行var p ,然后执行 gzb(2,2),所以p为undefined,全局变量x为2。

2.

var gzb = {  

 x : 0,  

 y : 0,  

 moveTo : function(x, y) {  

   this.x = this.x + x;  

     this.y = this.y + y;  

    }  

 }; 

gzb.moveTo(1,1);

gzb.x;    //1

根据图中的方法,是用dot(.)进行调用,则指向.moveTo之前的调用对象,即gzb对象,所以gzb.x值为1。

3.

var Obj = {
    gzb1:function () { 
        console.log(this);   
            function gzb2() { 
              console.log(this); 
            } 
        gzb2(); 
    } 
}; 
Obj.gzb1(); 

这段代码运行后会输出什么呢?应该是Obj对象和window,我们可以看到Obj.gzb1()是用dot(.)进行调用的,所以函数gzb1中的this应该指向Obj,然后在gzb1函数中还包含了一个gzb2函数,gzb2函数是怎么调用的呢?他是有gzb1函数进行调用的,也就是说它既没有使用new也没有使用dot(.)进行调用,所以gzb2中的this指向window。

二.this指向改变

this指向改变的方法有三种,分别是call,apply和bind。这三种方法理解起来比较简单。

1.

首先来看call,call方法可以传入两个参数,第一个参数就是你要指定的执行上下文,第二个用来向要执行的函数中传递参数。说白了,就是调用函数,但是让它在你指定的上下文下执行,来看下面这个例子:

function gzb1(x) {

this.x=x
    console.log(this);
function gzb2( ) {
    console.log(this);
}
gzb2();
}
var Obj = { };
gzb1.call(Obj,1);

上面这段代码的效果等同于下面这段代码,

var Obj = { 

gzb1:function (x) {
this.x=x
    console.log(this);
function gzb2( ) {
    console.log(this);
    }
gzb2();
  }
};

Obj.gzb1(1); 

2.

接下来看apply的用法,它和call的用法是很类似的,唯一的区别在于第二个参数,call必须全部列出来,不可传入数组,apply可以传入数组。

function gzb1(x) {

this.x=x
    console.log(this);
function gzb2( ) {
    console.log(this);
}
gzb2();
}
var Obj = { };

var a=[1,2,3,4]
gzb1.call(Obj,a);

3.

最后来看bind()的用法,它会创建一个函数的实例,其this值会被绑定到传给bind()函数的值。它和前两个的区别是它只是定义,不会立刻执行。

color='red';

var o={color:'blue'};

function sayColor(){

console.log(this.color);

}

var objectSaycolor=sayColor.bind(o);

objectSaycolor();//blue

在这里sayColor()调用bind()并传入对象o,创建了objectSayColor()函数。objectSayColor()函数的this值等于o,因此即使是在全局作用域中调用这个函数,也会看到blue。

猜你喜欢

转载自blog.csdn.net/qq_41635167/article/details/82798428