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函数中执行C#中的函数、字段
1.调用字段 cs文件的代码: ; protected void Page_Load(object sender, EventArgs e) { id = ; } js页面的代码: function ...
- js函数中获得当前被点击元素
问题描述:在html页面中点击<a>或者’按钮‘,进入js中的函数,在js函数中获得被点击那个<a>或‘按钮’元素 解决方法:方法一: html中: <a>标签:& ...
- 深入理解JS函数中this指针的指向
函数在执行时,会在函数体内部自动生成一个this指针.谁直接调用产生这个this指针的函数,this就指向谁. 怎么理解指向呢,我认为指向就是等于.例如直接在js中输入下面的等式: console.l ...
- js函数中this的不同含义
1.js函数调用过程中,js线程会进入新的执行环境并创建该环境的变量对象,并添加两个变量:this和arguments,因此可以在函数中使用这两个变量.需要注意的是,this变量不能重新赋值,而arg ...
- js函数中参数的传递
数据类型 在 javascript 中数据类型可以分为两类: 基本类型值 primitive type,比如Undefined,Null,Boolean,Number,String. 引用类型值,也就 ...
- js函数中的BOM和DOM
BOM 浏览器对象模型 screen对象 console.log(screen.width);// 屏幕宽度 console.log(screen.height);// 屏幕高度 console.l ...
- 将从model中获得的数据传到js函数中
刚遇到了一种情况,从controller中获得的model是一个集合,需要将这个集合循环放到标签中,并且需要为这些标签添加点击事件,每个值传入对应的点击事件函数中,由于model中的值是通过${ite ...
- js 函数中的this
资料 function 函数 没有"this"的持久概念, 调用函数时,创建this function hello(thing) { console.log(this + &quo ...
- js函数中写默认值的几种方式(常见的)
<script> <!--第一种写法,我更喜欢第一种写法直观一些--> function Person(name){ this.name = name || '默认名字乔丹'; ...
随机推荐
- CC2530ADC转换
一.ADC简介 ADC支持 14 位的模拟数字转换,具有多达12 位的 ENOB(有效数字位).它包括一个模拟多路转换器,具有多达8 个各自可配置的通道,以及一个参考电压发生器.转换结果通过DMA写入 ...
- Elasticsearch系列---Term Vector工具探查数据
概要 本篇主要介绍一个Term Vector的概念和基本使用方法. term vector是什么? 每次有document数据插入时,elasticsearch除了对document进行正排.倒排索引 ...
- 【Spark】如何用Spark查询IP地址?
文章目录 需求 思路 ip地址转换为Long类型的两种方法 ip地址转换数字地址的原理 第一种方法 第二种方法 步骤 一.在mysql创建数据库表 二.开发代码 需求 日常生活中,当我们打开地图时,会 ...
- shell 循环结构
前言 循环结构在编程中十分常见,也是程序中是较为重要的一部分,在bash中有 for,until,while 这三种语句可以进行重复执行部分程序流程,下面会进一步讨论这三个指令的使用以及注意事项 fo ...
- 第一行Kotlin系列(三)Intent 向上一页返回数据onActivityResult的使用
1.MainActivity.kt跳转处理 声明全局的按钮对象 private lateinit var button8: Button 实例化按钮对象 button8 = findViewById( ...
- 【hdu5100】棋盘覆盖
http://acm.hdu.edu.cn/showproblem.php?pid=5100 题目大意: 用1*k的木块铺n*n的棋盘,求多铺满多少个单位格. 方法: n < k,显然无解:n ...
- Selenium + Python + Chrome 自动化测试 环境搭建
一.下载Python 相关的教程很多,此处不详细记录了,下面是官网下载地址: https://www.python.org/downloads/ 我使用的python版本为 Python 3.6.1 ...
- JavaScript 事件参考
onabort 图像加载被中断 onblur 元素失去焦点 onchange 用户改变域的内容 onclick 鼠标单击事件 ondblclick 鼠标双击事件 onerror ...
- mybatis association的使用
在上一篇文章中介绍了collection的使用以及java bean,表的结构,今天进行association使用的学习,在多对一的映射关系中,查询到多的一方顺带查询出一的一方是常见的!在此例子中,在 ...
- IDEA快捷键(windows)
Ctrl+Shift + Enter,语句完成“!”,否定完成,输入表达式时按 “!”键Ctrl+E,最近的文件Ctrl+Shift+E,最近更改的文件Shift+Click,可以关闭文件Ctrl+[ ...