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 || '默认名字乔丹'; ...
随机推荐
- 解决使用nlpir分词,遇到License过期问题
问题:使用pynlpir分词,遇到License过期问题 抛出异常:pynlpir.LicenseError: Your license appears to have expired. Try ru ...
- uCOS2014.1.7
主要关于任务堆栈: 在计算机中一般设置一个专用的地址寄存器用来存放堆栈的栈顶地址,这个寄存器称为堆栈指针(SP). 任务堆栈有两种,一种是地址向下增长的,PC就是采用这样的堆栈: 另一种是地址向上增长 ...
- Windows 10 IoT Core用PWM控制器控制树莓派LED灯亮度
我接到一个需求,需要调节LED灯的亮度,且是从上位机进行控制,我了解到树莓派也有PWM,就准备通过PWM来控制灯的亮度. PWM又叫脉宽调制,是用微处理器的数字输出来对模拟电路进行控制,对模拟信号电平 ...
- js对页面中的内容进行拼音搜索,只对后台已经传过来的页面数据进行索引
实现输入拼音(可以使用拼音首字母来查),来查询出已经存在于页面的数据 注意:这种写法只能适用于页面中已经存在的数据进行检索,大体意思是将本页内的数据拼接成一个字符串,然后通过该字符串去检索匹配的字符串 ...
- Redis系列(七)Redis面试题
Redis 系列: Redis系列(一)Redis入门 Redis系列(二)Redis的8种数据类型 Redis系列(三)Redis的事务和Spring Boot整合 Redis系列(四)Redis配 ...
- 00001- layui 表格的默认工具栏添加自定义按钮
首先定义table: var tableIns = table.render({ elem:'#businessUserListTable' ,url: ctx+'/business/business ...
- 【雕爷学编程】MicroPython动手做(07)——零基础学MaixPy之机器视觉
机器视觉 machine vision机器视觉是人工智能正在快速发展的一个分支.机器视觉作为生产过程中关键技术之一,在机器或者生产线上,机器视觉可以检测产品质量以便将不合格的产品剔除,或者指导机器人完 ...
- scroll 方法 获取滚轴距离顶部高度
$(window).scroll(function(){ var supportPageOffset = window.pageXOffset !== undefined; // 判断是否支持page ...
- 为什么Tableviewcell创建时可以不判空
dequeueReuseableCellWithIdentifier:与dequeueReuseableCellWithIdentifier:forIndexPath:的区别: 前者不必向tableV ...
- 当 RocketMQ 遇上 Serverless,会碰撞出怎样的火花?
作者 | 元毅 阿里巴巴高级开发工程师 阿里巴巴云原生公众号后台回复 Knative,免费下载<Knative 云原生应用开发指南>电子书! 想必大家都比较了解 RocketMQ 消息服 ...