关于这个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. CC2530ADC转换

    一.ADC简介 ADC支持 14 位的模拟数字转换,具有多达12 位的 ENOB(有效数字位).它包括一个模拟多路转换器,具有多达8 个各自可配置的通道,以及一个参考电压发生器.转换结果通过DMA写入 ...

  2. Elasticsearch系列---Term Vector工具探查数据

    概要 本篇主要介绍一个Term Vector的概念和基本使用方法. term vector是什么? 每次有document数据插入时,elasticsearch除了对document进行正排.倒排索引 ...

  3. 【Spark】如何用Spark查询IP地址?

    文章目录 需求 思路 ip地址转换为Long类型的两种方法 ip地址转换数字地址的原理 第一种方法 第二种方法 步骤 一.在mysql创建数据库表 二.开发代码 需求 日常生活中,当我们打开地图时,会 ...

  4. shell 循环结构

    前言 循环结构在编程中十分常见,也是程序中是较为重要的一部分,在bash中有 for,until,while 这三种语句可以进行重复执行部分程序流程,下面会进一步讨论这三个指令的使用以及注意事项 fo ...

  5. 第一行Kotlin系列(三)Intent 向上一页返回数据onActivityResult的使用

    1.MainActivity.kt跳转处理 声明全局的按钮对象 private lateinit var button8: Button 实例化按钮对象 button8 = findViewById( ...

  6. 【hdu5100】棋盘覆盖

    http://acm.hdu.edu.cn/showproblem.php?pid=5100 题目大意: 用1*k的木块铺n*n的棋盘,求多铺满多少个单位格. 方法: n < k,显然无解:n ...

  7. Selenium + Python + Chrome 自动化测试 环境搭建

    一.下载Python 相关的教程很多,此处不详细记录了,下面是官网下载地址: https://www.python.org/downloads/ 我使用的python版本为 Python 3.6.1 ...

  8. JavaScript 事件参考

     onabort  图像加载被中断  onblur  元素失去焦点  onchange  用户改变域的内容  onclick  鼠标单击事件  ondblclick  鼠标双击事件  onerror ...

  9. mybatis association的使用

    在上一篇文章中介绍了collection的使用以及java bean,表的结构,今天进行association使用的学习,在多对一的映射关系中,查询到多的一方顺带查询出一的一方是常见的!在此例子中,在 ...

  10. IDEA快捷键(windows)

    Ctrl+Shift + Enter,语句完成“!”,否定完成,输入表达式时按 “!”键Ctrl+E,最近的文件Ctrl+Shift+E,最近更改的文件Shift+Click,可以关闭文件Ctrl+[ ...