前端开发人员在进阶过程中总会遇到一个疑难杂症:Javascript的this
this到底指向什么哪个对象啊?
要爆炸了有木有?

1、this

在函数执行时,this 总是指向调用该函数的对象。要判断 this 的指向,其实就是判断 this 所在的函数属于谁。

1.1、姜浩五大定律

  • 通过函数名()直接调用:this指向window;
  • 通过对象.函数名()调用的:this指向这个对象;
  • 函数作为数组的一个元素,通过数组下标调用的:this指向这个数组;
  • 函数作为window内置函数的回调函数调用:this指向window,setTimeout,setInterval等……;
  • 函数作为构造函数,用new关键字调用时:this指向新new出的对象。

对于this指向谁,我们记住一句就行:谁最终调用函数,this就指向谁!

记住:

  • this指向的永远只可能是对象
  • this指向谁,永远不取决于this写在哪!而是取决于函数在哪调用!!!

2、this的用法

准备了几个测试,快来看看你能否完全答对输出?
可先根据代码猜下输出内容,先自己思考一下印象才会更深哦
在控制台复制代码回车查看对应的this输出内容

2.1 作为普通函数调用

// 在非严格模式下
var name = 'hello';
function f1(){console.log(this); console.log(this.name);name = this.name + 'world'
}
f1();
console.log(this.name);// 在严格模式下
function f2() {"use strict";console.log(this);
}
f2();

解析:

  • 直接调用的情况下,不论是严格模式还是非严格模式,this的指向都是全局对象,在浏览器中这个值是window对象。

  • 一个普通的函数调用时,在非严格模式下this指向window或global对象严格模式下,this指向undefined

2.2 作为对象的方法调用

var name = 'globalName'
var obj = {name : 'Yushia',getName : function(){console.log(this.name);}
}obj.getName();
var fun2 = obj.getName;
fun2();

解析:

  • 函数作为一个对象里的方法被调用,this 指向该对象

  • 把对象的方法赋值给一个变量,再调用这个变量,此时 this 指向了全局对象。给 fun2 赋值,其实是相当于:

var fun2 = function(){console.log(this);
}

可以看出,此时的 this 已经跟 obj 没有任何关系了。这时 fun2 是作为普通函数调用

2.2.1 对象多层嵌套

function foo(){console.log(this.name)
}
var shiny={name:'shiny',foo:foo
}
var red={name:'red',obj:shiny}
red.obj.foo()

解析:

不管你的对象嵌套多深,this只会绑定为直接引用该函数的地址属性的对象

2.3 作为构造器调用

2.3.1 无返回值

function Person(n, a){this.name = n;this.age = a;console.log(this);
}var obj = new Person("Yushia", 18);
console.log(obj.name);
Person("Yushia", 18);

解析:

  • new 创建对象的时候调用了构造函数
  • 构造函数和普通函数的区别在于调用方式,而不是定义方式。
  • new关键字改变了函数内this的指向,使其指向刚创建的对象

2.3.2 有返回值–返回一个对象

function Person(n, a){this.name = n;this.age = a;return {name: "Lucy",};
}var obj = new Person("Yushia", 18);
Person("Yushia", 18);
console.log(obj.name);
console.log(obj.age);

解析:

  • 如果构造函数显式的返回一个对象,那么 this 则会指向该返回对象。

2.3.3 有返回值–返回基本数据类型非对象

function Person(n, a){this.name = n;this.age = a;return  "Lucy";
}var obj = new Person("Yushia", 18);
Person("Yushia", 18);
console.log(obj.name);
console.log(obj.age);

解析:

  • 构造函数的返回值如果是基本数据类型,那返回值和得到的对象无关

2.4 bind() 、apply() 、call() 调用

var name = "小王",age=18;var obj = {name: '小明',age:20,myFun:function(province,city){console.log( this.name + "年龄" + this.age +",来自" + province + "省" + city +"市" ) ;}
}var db = {name:"Yushia",age:18
}obj.myFun.call(db,'福建','福州');
obj.myFun.apply(db,['福建','福州']);
obj.myFun.bind(db,'福建','福州')();
obj.myFun.bind(db,['福建','福州'])();

解析:

  • call 、bind 、 apply 这三个函数的 第一个参数都是 this 的指向对象,第二个参数差别就来了:

  • call 的参数是直接放进去的,第二第三第 n 个参数全都 用逗号分隔 ,直接放到后面 obj.myFun.call(db,‘成都’, … ,‘string’ )。

  • apply 的所有参数都必须放在一个 数组 里面传进去 obj.myFun.apply(db,[‘成都’, …, ‘string’ ])。

  • bind 除了返回是函数以外,它 的参数和 call 一样

当然,三者的参数不限定是 string 类型,允许是各种类型,包括函数 、 object 等等!

2.5 setTimeout & setInterval

function Person() {  this.age = 0;  setTimeout(function() {console.log(this);}, 1000);
}var p = new Person();function Person2() {  this.age = 0;  setTimeout((function() {console.log(this);}).bind(this), 1000);
}var p = new Person2();

解析:

  • 对于延时函数(setTimeout & setInterval)内部的回调函数的this指向全局对象window
  • 可以通过bind方法改变其内部函数的this指向

2.6 DOM 事件处理函数中的 this & 内联事件中的 this其

this 指向触发该事件的元素

<!--   输出"Click Me"  -->
<input type="button" id="myBtn" value="Click Me" onclick="consloe.log(this.value)"><script>
var btn=document.getElementById('myBtn');
btn.onclick=function(){console.log(this.id);  //"myBtn"
}
</script>

2.7 箭头函数中的 this

function Person() {  this.age = 0;  setTimeout(() => {console.log(this)}, 1000);
}var p = new Person();var obj = {a: () => {console.log(this)}
}
obj.a()var obj2 = {a: () => {console.log(this)}
}
obj2.a.call('123')

解析:

  • 箭头函数会默认绑定外层this的值,所以在箭头函数中this的值和外层的this是一样的。
  • 不能用call方法修改里面的this

2.8 闭包中的this

var name = "window";var obj = {name: "Yushia",say:function(){var that = this;console.log(this.name);return function(){console.log(this.name);console.log(that.name);}}
}
obj.say()();
obj.say().call(obj);

解析:

因为闭包并不属于这个对象的属性或方法。所以在闭包中的 this是指向window.

  • 闭包中的this指向的是window对象,this.name=window.name
  • obj.say().call(obj) 这里通过call方法把this的指向换成了obj
  • 在方法内部改变this指向,对象中的say方法中this是指向obj,使用that代替this,在闭包函数中写成that.name 那么结果指向obj

结语

你答对了?在评论打出你对了多少?

将这些都掌握了,以后再看见this就不慌了

深入理解 JavaScript 之 this指向详解相关推荐

  1. Javascript this关键字 指向详解

    Javascript this关键字 指向详解 面向对象语言中 this 表示当前对象的一个引用.在 JavaScript 中 this 不是固定不变的,它会随着执行环境的改变而改变. 1) 单独使用 ...

  2. Javascript常用的设计模式详解

    Javascript常用的设计模式详解 阅读目录 一:理解工厂模式 二:理解单体模式 三:理解模块模式 四:理解代理模式 五:理解职责链模式 六:命令模式的理解: 七:模板方法模式 八:理解javas ...

  3. 众望所归的《JAVASCRIPT凌厉开发--EXT详解与实践 》终于上市了!

    大家好,我是这本书的策划编辑,经过努力,这本书终于上市了. 从创作开始,我们的目标就是写一本真正适合开发者参考和借鉴的EXT书,写作过程中,经过了无数次讨论和痛苦修订,感谢三位作者付出的艰辛劳动. 这 ...

  4. JavaScript中的this详解

      前  言  this  JavaScript中的this详解 this详解 This的指向有几种情况?如何人为控制? [谁调用this,this指向谁!!] [this的指向,不关心this写在哪 ...

  5. 用html js制作迷宫,JavaScript生成随机迷宫详解

    本篇教程介绍了JavaScript生成随机迷宫详解,希望阅读本篇文章以后大家有所收获,帮助大家对JavaScript的理解更加深入. < #先看生成随机迷宫的代码吧↓ 1 2 3 生成随机迷宫v ...

  6. JavaScript Promise返回值详解

    JavaScript Promise返回值详解 Promise回顾 Promise回调函数返回非Promise值 Promise回调函数返回Promise对象 Promise回调函数中抛出错误 总结 ...

  7. 前端this指向详解

    前端this指向详解 什么是this this在不同应用场景中的取值 普通函数(非箭头函数)被调用时的this指向 普通函数(非箭头函数)作为对象方法被调用时的this指向 普通函数(非箭头函数)作为 ...

  8. 2020-11-26((《深入理解计算机系统》多级页表详解)补充)

    今日总结: 今天主要把11-25(<深入理解操作系统>多级页表详解)第一部分看懂,并把它做了一个补充,让看博客的各位更能深刻理解,谢谢各位支持,一起加油 明日目标: 复习大学物理,线性代数 ...

  9. JavaScript中getBoundingClientRect()方法详解

    JavaScript中getBoundingClientRect()方法详解 getBoundingClientRect() 这个方法返回一个矩形对象,包含四个属性:left.top.right和bo ...

最新文章

  1. linux存储--dup和dup2函数解析(十八)
  2. 全球及中国汽车后市场规模格局及经营趋势研究报告2021-2027年
  3. hydra图形化工具下载_Hydra for Mac 4.0.4 专业的摄影图像工具
  4. git初使用(本地创建后第一次提交到git)
  5. c php数据,C 数据类型
  6. 推荐+1置顶+1(分享、讨论、实现)通用软件注册功能之建立有效的软件保护机制...
  7. Linxu 学习记录
  8. MediaPlayer控件的初探
  9. CodeForces 13C【DP】
  10. java多线程nullpointerexception_温故而知新!越是基础越容易被忽略,java最全基础知识,附赠资料...
  11. deepin php docker,Deepin15.10安装Docker
  12. [ioi2008]Island 岛屿
  13. AMD OpenCL Programming Guide - OpenCL Architecture
  14. python中if语句中可用break_python跳出if语句
  15. 基于SDCC的工程化实践
  16. 学习coreldraw
  17. 二进制bit0是什么意思_阜平吧在讨论5G的问题,感觉挺有意思,科普下……
  18. 期货什么是涨跌(期货是看涨还是看跌)
  19. 二十一世纪大学英语读写教程(第四册)学习笔记(原文)——3 - How to Change Your Point of View(如何改变你的观点)
  20. 信息网络传播权 服务器,信息网络传播权的特征

热门文章

  1. Linux-groups
  2. 什么是相对路径?什么是绝对路径?
  3. 开源作者丢了个炸弹,记colors.js与faker.js事件
  4. DirectX12(D3D12)基础教程(十一)——几个“上古时代”的基于Pixel Shader的滤镜效果
  5. 梦网短信服务真的垃圾
  6. 灌区配水调度管理系统-灌区配套与节水改造
  7. Lucene系列:(11)异步分页
  8. 称通过帮买服务买到泡水车 购车者诉“瓜子网”索赔
  9. linux之文件内容显示
  10. 提示“windows无法配置此无线连接,如果您已经起用其他程序管理此无线连接,请使用该软件.....”解决方法