js函数中的this关键字

Posted dearxiangxiao

tags:

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

关于这个this关键字,也是很多项目中常常被用到的,那么,有人也许会问,干嘛要用this呢,在函数被调用时,直接指明是什么对象在调用不就行了?还整那么个模模糊糊的概念出来干嘛?不过嘛,存在即真理,既然有这么个东西,那也就有他存在的意义,下面来看看吧。

 

首先,我们要先回忆一下js函数都有哪几种调用的场合,有如下几种场合:

1、很常规的调用(即直接调用,其实你发现也是全局调用);

2、作为某个对象的豆哥方法被调用;

3、作为构造函数,用来新建某个新对象(object);

4、很让人头大的apply调用(在实现部分继承的时候经常这么干)。

 

好了,一起来看看上述几种情况下this关键字是怎样被玩的出神入化的。

一、纯粹的函数调用

这是函数的最通常用法,属于全局性调用,因此this就代表全局对象Global,那么这里Global很多人又很迷惑了,实则在浏览器环境下,Global也即是window对象,global对象是单体内置对象,即不依赖宿主环境的对象,而window对象依赖浏览器。

看下面这段代码:

function test(){

  this.name = "dearxiangxiao";

  console.log(this.name );

}

test();  //dearxiangxiao

感觉还是很神奇的,不知不觉test函数里面定义的属性,在外面也可以读取了?对代码做一些修改,如下:

var name = "xiangxiao";

function test(){

  this.name  = "dearxiangxiao";

}

test();

alert(name); //  dearxiangxiao

可以看出,在执行完test函数之后,name的值被改变了,原因何在?这里就是这个调用test的对象是Global在作怪,既然test是被全局对象Global调用的,那么this也就指向Global对象了,全局对象的属性,当然可以读取并修改了,没啥错。

 

二、作为对象方法的调用

函数还可以作为某个对象的方法调用,这时this就指这个上级对象,也来看一段代码:

function test(){

  console.log("my name is "+this.name + " and my profession is "+this.profession);

};

var person = {};

person .name= "dearxiangxiao";

person.profession = "projector";

person.interduce= test;

person .interduce(); // my name is dearxiangxiao,and my profession is projector

这里很好理解,既然是person在调用test函数,那么理所应当的this指向的是person实体,也就是前面说的调用函数的上一级对象,它的name和profession 属性当然应该被读取出来了。

 

三、作为构造函数调用

所谓构造函数,就是通过这个函数生成一个新对象(object)。这时,this就指这个新对象,也来看一段代码,将一中的例子做轻微的修改:

var name = "xiangxiao";

function Person(){

  this.name  = "dearxiangxiao";

}

var person1 = new Person();

console.log(name); // xiangxiao

console.log(person1.name);   //  dearxiangxiao

可以看出,this指向的对象是刚刚新建的person1,读取出了它的名称dearxiangxiao,而直接打印name变量,值仍然未变,为之前的xiangxiao。这更加表明this指向person1,而不是Global对象。

 

四、apply调用

apply()是函数对象的一个方法,它的作用是改变函数的调用对象(实则是将某某对象的某个方法放到另一个好基友对象那里去执行),它的第一个参数就表示改变后的调用这个函数的对象。因此,this指的就是这第一个参数。

关于这个apply,可能大多数人不太喜欢用它,要想调用某个对象直接调用不就好了么?但是应该想到,假如你想调用别人写好的某个方法,某些参数变量却要用到你自己的,怎么办?apply和call就派上用场了,这也是js面向对象思维转换的重要一环,必须理解的(关于apply和call具体详情,请看我的另一篇博文:js面向对象思维转换的一个阶梯:apply和call)。

 

下面还是来看个例子吧,这里把三中的例子做一些轻微的修改:

var name = "xiangxiao";

function test(){

  console.log(this.name);

}

var person1 = new Person();

person1.name = "dearxiangxiao";

person1.interduce = test;

person1.interduce.apply();  // 这里输出的四xiangxiao

怎么回事,不是说好了的要改变函数的调用对象么?怎么还是被Global调用了?不急不急,来看看apply后面的括号里,没任何东西,默认没有残数时是全局对象Global,因此,此处也就真的是调用出了Global的name变量。那person1.interduce.apply()怎么理解呢?可以这么理解:将person1实体的interduce方法放到Global对象上去执行。

好了,我们刚刚在前面说了,apply后面括号里的第一个参数,即为this的指向,那么改一改上面的最后一句代码吧,如下:

person1.interduce.apply(person1); // 这里输出的就是dearxiangxiao

 

得到person1的name属性值了,突然冒出个想法,这里person1.interduce.apply(person1) 理解出来貌似很拗口额:将person1实体对象的interduce方法放到person1实体对象上去执行,什么鬼?自己的方法自己直接调用不好么?写成 person1.interduce()就行了噻!!!当然可以,那样更简洁,不过,这就是apply方法的特点所致吧,自己的方法,转一圈回到自己手里被调用了,还给出个冠冕堂皇的解释,哈哈,就不吐槽了,我们还是要看到apply带给我们的诸多好处的。

这篇博文就是这么多内容了,希望大家会喜欢。

以上是关于js函数中的this关键字的主要内容,如果未能解决你的问题,请参考以下文章

js中的this关键字详解

关于JS中的this关键字

js函数中的this关键字

this关键字

js中的this关键字详解[转]

前端js中的this