关于这个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关键字的更多相关文章

  1. 在JS函数中执行C#中的函数、字段

    1.调用字段 cs文件的代码: ; protected void Page_Load(object sender, EventArgs e) { id = ; } js页面的代码: function ...

  2. js函数中获得当前被点击元素

    问题描述:在html页面中点击<a>或者’按钮‘,进入js中的函数,在js函数中获得被点击那个<a>或‘按钮’元素 解决方法:方法一: html中: <a>标签:& ...

  3. 深入理解JS函数中this指针的指向

    函数在执行时,会在函数体内部自动生成一个this指针.谁直接调用产生这个this指针的函数,this就指向谁. 怎么理解指向呢,我认为指向就是等于.例如直接在js中输入下面的等式: console.l ...

  4. js函数中this的不同含义

    1.js函数调用过程中,js线程会进入新的执行环境并创建该环境的变量对象,并添加两个变量:this和arguments,因此可以在函数中使用这两个变量.需要注意的是,this变量不能重新赋值,而arg ...

  5. js函数中参数的传递

    数据类型 在 javascript 中数据类型可以分为两类: 基本类型值 primitive type,比如Undefined,Null,Boolean,Number,String. 引用类型值,也就 ...

  6. js函数中的BOM和DOM

    BOM 浏览器对象模型  screen对象 console.log(screen.width);// 屏幕宽度 console.log(screen.height);// 屏幕高度 console.l ...

  7. 将从model中获得的数据传到js函数中

    刚遇到了一种情况,从controller中获得的model是一个集合,需要将这个集合循环放到标签中,并且需要为这些标签添加点击事件,每个值传入对应的点击事件函数中,由于model中的值是通过${ite ...

  8. js 函数中的this

    资料 function 函数 没有"this"的持久概念, 调用函数时,创建this function hello(thing) { console.log(this + &quo ...

  9. js函数中写默认值的几种方式(常见的)

    <script> <!--第一种写法,我更喜欢第一种写法直观一些--> function Person(name){ this.name = name || '默认名字乔丹'; ...

随机推荐

  1. 数据结构与算法:栈(Stack)的实现

    栈在程序设计当中是一个十分常见的数据结构,它就相当于一个瓶子,可以往里面装入各种元素,最先装进这个瓶子里的元素,要把后装进这个瓶子里的全部元素拿出来完之后才能够把他给拿出来.假设这个瓶子在桌上平放,左 ...

  2. JavaScript 浅析数组对象与类数组对象

    数组(Array对象) 数组的操作 创建数组方法 添加与修改数组元素 删除数组元素 使用数组元素 遍历数组元素 多维数组 数组相关的函数 concat() join() pop() push() sh ...

  3. 201771010113 李婷华 《面向对象程序设计(java)》第十五周总结

    一.理论知识部分 JAR文件 Java程序的打包:程序编译完成后,程序员将.class文件压缩打包为.jar文件后,GUI界面程序就可以直接双击图标运行. .jar文件(Java归档)既可以包含类文件 ...

  4. LeetCode--Array--Two sum (Easy)

    1.Two sum (Easy)# Given an array of integers, return indices of the two numbers such that they add u ...

  5. 小程序如何动态修改标题navigationBarTitleText

    首先我们先设置标题.进入页面所在的json文件加入以下代码即可成功设置: "navigationBarTitleText": "我是标题啊!", 然后修改这个标 ...

  6. 1013 Battle Over Cities (25分) 图的连通分量+DFS

    题目 It is vitally important to have all the cities connected by highways in a war. If a city is occup ...

  7. C# 数据操作系列 - 7. EF Core 导航属性配置

    在上一篇,大概介绍了Entity Framework Core关于关系映射的逻辑.在上一篇中留下了EF的外键映射没有说,也就是一对一,一对多,多对一,多对多的关系等.这一篇将为大家细细分析一下,如何设 ...

  8. luoguP3121解题报告

    p3121 本题首先利用一个手写栈,使元素可以快速出栈,再利用栈快速查询上一个元素在trie中的位置.

  9. 我的linux学习日记day3

    ifconfig  查看网卡信息 uname 查看系统内核.版本信息 cat /etc/redhat-release uptime 查看系统负载信息 top命令的第一行信息 free 查看内存信息 f ...

  10. php5.2安装memcached 扩展

    需要注意版本号,好坑. libmemcached release 1.0.16 - installed from sourcephp-memcached release 2.1.0 - install ...