因为JavaScript 中this 是在运行期进行绑定的,因此JavaScript 中this 关键字具备多重含义。

具体在实际应用中,this的指向大致可以分为下面4种。

  1. 作为对象的方法调用   obj.a()
  2. 作为普通函数调用    a()
  3. 构造函数调用        var b = new a(); 
  4. function.prototype.call或function.prototype.apply调用

作为对象的方法调用 和 作为普通函数调用

 window.a = 2;
var obj = {
a:1,
getA:function(){
console.log(this.a);
}
}
obj.getA(); //输出1,作为对象的方法调用,this指向当前对象
var x = obj.getA;
x(); //输出2,作为普通函数调用,this全部指向window对象。

注意,不管x之前是obj.getA,还是其他某个对象的属性,只要最后是以x(),fun()这种方式调用的,均视为普通函数调用,此时this指向window对象

但是,在ECMAScript5的strict模式下,作为函数调用的 this被规定不会指向全局对象

 window.a = 2;
var obj = {
a:1,
getA:function(){
"use strict"
console.log(this.a);
}
}
var x = obj.getA;
x(); //underfined

作为构造函数调用

通常情况下,构造函数里的this指向返回的这个对象,但是如果构造器显示地返回了一个object类型的对象,则this指向这个返回的object对象
 var Myclass = function(){
this.name = 'beidan';
}
var obj = new Myclass();
console.log(obj.name);//beidan var Myclass = function(){
this.name = 'beidan';
return{ //显示的返回一个对象,注意!既要是显示,即有return,也要是对象{}
name:'test'
}
}
var obj = new Myclass();
console.log(obj.name);//test

作为function.prototype.call或function.prototype.apply调用

  • 理解call,apply

call,apply都是为了改变函数体内部 this 的指向。例如,fun1.call()或者fun1.apply() 都是为了改变fun1函数内部的this指向。

二者的作用完全一样,只是接受参数的方式不太一样。

func1.call(this, arg1, arg2);        //参数列表arg1,arg2
func1.apply(this, [arg1, arg2]);   //参数数组 [arg1,arg2]
 
第一个参数指定那个了函数体内this对象的指向,他可以任何一个 JavaScript 对象(JavaScript 中一切皆对象),如果为null,则函数体内的this会指向默认的宿主对象,在浏览器中则是window。
 
第二个参数,call 需要把参数按顺序传递进去,而 apply 则是把参数放在数组里。
当你的参数不确定数量时用 apply ,然后把参数 push 进数组传递进去。或者也可以通过 arguments来获取所有的参数。这样看来,apply的使用率更高。
 
  • call,apply的用途
1.修正this的指向
比如,在实际开发中,会出现以下这种问题
 document.getElementById('div1').onclick = function(){
console.log(this.id); //div1
var func = function(){
console.log(this.id);
}
func(); //通过普通函数调用,this指向window,输出undefined
}
这时我们可以用call来修正func 函数内this的指向。
 document.getElementById('div1').onclick = function(){
console.log(this.id); //div1
var func = function(){
console.log(this.id);
}
func.call(this); //使用call,使func函数内部的this指向当前的函数对象,输出div1
}

2.模拟继承(借用其他对象的方法)

  • 例子一:其他对象(banana)借用apple中的say方法
 function fruits() {}
fruits.prototype = {
color: "red",
say: function() {
console.log("My color is "+ this.color);
}
}
var apple = new fruits;
apple.say(); //My color is red

但是,如果我们还有其它 2个对象 banana= {color : "yellow"} ,orange = {color:‘orange’},想使用say方法,但是又不想对它们重新定义say方法。

那么,我们可以用apply或者call 借用 fruit里面的say方法
 banana = {
color: "yellow"
};
orange = {color:‘orange’};
apple.say.call(banana); //My color is yellow
apple.say.apply(orange ); //My color is orange

也就是说,当一个 object 没有某个方法(本例子中banana没有say方法),但是其他的有(本例子中apple有say方法),我们可以借助call或apply用其它对象的方法来操作。

再看几个例子巩固记忆
  • 例子二:获取数组中的最大值和最小值
 var numbers = [5, 458 , 120 , -215 ];
var maxInNumbers = Math.max.apply(Math, numbers), //
maxNumbers = Math.max.call(Math,5, 458 , 120 , -215, 666); //

number 本身没有 max 方法,但是 Math 有,我们就可以借助 call 或者 apply 使用其方法。

以上就是this在JavaScript中不同情况下的指向。

如果这篇文章对你有帮助,就给我一点赞赏吧~~~

通俗易懂------this指向的更多相关文章

  1. 通俗易懂浅谈理解ES6类this不同指向问题

    1. class Btn{ //定义的一个类 constructor(id){ // constructor是一个构造函数,是一个默认方法,通过 new 命令创建对象实例时,自动调用该方法.一个类必须 ...

  2. 关于一个通俗易懂的FFT的C语言实现教程

    找到一个通俗易懂并且神奇并且有趣的FFT算法C语言实现教程:http://www.katjaas.nl/FFTimplement/FFTimplement.html 只要对矩阵比较熟悉就能在教程的辅助 ...

  3. JS中OOP之模拟封装和继承和this指向详解

    大家好,今天我带大家学习一下js的OOP, 大家都知道,面向对象有三个基本特征,继承,封装和多态,面向对象的语言有那么几种,C++,PHP,JAVA等,而功能强大的JS可以模拟实现面向对象的两大特征, ...

  4. 常用DOS命令之通俗易懂篇

    目录 常用DOS命令之通俗易懂篇 Arp 命令 Assoc 关联 At 计划服务 Attrib 属性 Cd=chdir 目录 Cipher Cls 清屏 Color 颜色 Comp 比较 Compac ...

  5. 1. 通俗易懂解释知识图谱(Knowledge Graph)

    1. 通俗易懂解释知识图谱(Knowledge Graph) 2. 知识图谱-命名实体识别(NER)详解 3. 哈工大LTP解析 1. 前言 从一开始的Google搜索,到现在的聊天机器人.大数据风控 ...

  6. 通俗易懂,C#如何安全、高效地玩转任何种类的内存之Span的脾气秉性(二)。 异步委托 微信小程序支付证书及SSL证书使用 SqlServer无备份下误删数据恢复 把list集合的内容写入到Xml中,通过XmlDocument方式写入Xml文件中 通过XDocument方式把List写入Xml文件

    通俗易懂,C#如何安全.高效地玩转任何种类的内存之Span的脾气秉性(二).   前言 读完上篇<通俗易懂,C#如何安全.高效地玩转任何种类的内存之Span的本质(一).>,相信大家对sp ...

  7. 通俗易懂,什么是.NET?什么是.NET Framework?什么是.NET Core? .Net Web开发技术栈

    通俗易懂,什么是.NET?什么是.NET Framework?什么是.NET Core?   什么是.NET?什么是.NET Framework?本文将从上往下,循序渐进的介绍一系列相关.NET的概念 ...

  8. 通俗易懂,什么是.NET?什么是.NET Framework?什么是.NET Core?(转)

    通俗易懂,什么是.NET?什么是.NET Framework?什么是.NET Core?(转) 一.总结 一句话总结:.NET是一个平台,包含多种语言,比如(C#.Visual Basic.C++/C ...

  9. 3万字长文概述:通俗易懂告诉你什么是.NET?什么是.NET Framework?什么是.NET Core?

    [转载]通俗易懂,什么是.NET?什么是.NET Framework?什么是.NET Core? 什么是.NET?什么是.NET Framework?本文将从上往下,循序渐进的介绍一系列相关.NET的 ...

随机推荐

  1. UWP 矢量字体图标(iconfont)使用

    本文使用 阿里巴巴开源字体: 选择矢量字体图标: 查看或编辑 Unicode编码 或字体名称 下载到本地,添加到uwp项目 代码中写法 Text:Unicode编码 FontFamily:文件路径#字 ...

  2. NPOI 读取excel到DataTable 读取隐藏列 读取公式列

    处理思路: 1.打开excel 用NPOI进行读取: 2.读取第一个Sheet: 读取过程中: a.先设置相应列 不隐藏 b.读取Cell时 先判断是否的包含公式 相应代码如下: public sta ...

  3. hdu2527哈夫曼编码

    /* Safe Or Unsafe Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) T ...

  4. 对"构建之法“的理解和困惑

    对"构建之法"的理解和困惑        本人"学沫沫"一个,对于之前的编程学习虽不大"感冒",但秉着对自己负责的态度进行了基础学习.   ...

  5. 利用Google Speech API实现Speech To Text

    很久很久以前, 网上流传着一个免费的,识别率暴高的,稳定的 Speech To Text API, 那就是Google Speech API. 但是最近再使用的时候,总是返回500 Error. 后来 ...

  6. java 空指针异常(java.lang.NullPointerException)

    在Java中对值为null的指针调用任何方法,就会引发空指针异常(java.lang.NullPointerException).空指针异常绝对 是Java中最难查找和调试的一种异常,你永远无法得到任 ...

  7. CPU相关知识-寄存器与存储器的区别

    存储器一般在CPU外,一般指硬盘,U盘等可以在切断电源后保存资料的设备,容量一般比较大,缺点是读写速度都很慢,普通的机械硬盘读写速度一般是 50MB/S左右.内存和寄存器就是为了解决存储器读写速度慢而 ...

  8. java 21 - 12 随机访问流(不属于IO流)

    随机访问流: RandomAccessFile类不属于流,是Object类的子类. 但它融合了InputStream和OutputStream的功能. 支持对文件的随机访问读取和写入. public ...

  9. js原生捕鱼达人(三)--完结

    先给分享下我写完的效果,github有点卡,我没有压缩代码,不过效果可以看到 https://jasonwang911.github.io/ 转载请注明'转载于Jason齐齐的博客http://www ...

  10. tp登录方法

    先根据输入的名字检测是否存在数据表中,如果有继续进一步验证密码,除了select(),find()可以查询数据外,还可以用getByXxx()指定数据表字段查询, 比如数据表有username字段,就 ...