一文搞懂this指向
1、this的默认绑定
this 默认指向了 window
// 1、全局环境下的this指向了windowconsole.log(this);// 2、函数独立调用,函数内部的this也指向了windowfunction fn() {console.log(this);}fn();// 3、被嵌套的函数独立调用时,this默认指向了windowvar a = 0;var obj = {a: 2,foo: function () {// 函数当作对象的方法调用时,this指向了objvar that = this; // objfunction test() {console.log(that.a); // window}test();}}obj.foo();// 4、IIFE 自执行函数中内部的this指向了windowvar a = 10;function foo() {console.log(this);(function test(that) {console.log(that.a);})(this)}var obj = {a: 2,foo: foo}obj.foo();(function () {console.log(this); //window})()// 5、闭包中的this默认指向了windowvar a = 0;var obj = {a: 2,foo: function () {var c = this.a;return function test() {console.log(this); //windowreturn c;}}}var fn = obj.foo();fn();
2、this的隐式绑定
// 当函数当作方法来调用,this指向了直接对象function foo() {console.log(this.a);}var obj = {a: 1,foo: foo,obj2: {a: 2,foo: foo}}// foo()函数的直接对象是obj,this的指向指向了直接对象obj.foo();// foo()函数的直接对象是obj2,this的指向指向了直接对象obj.obj2.foo();
3、this的显示绑定
// call()、apply()、bind()把对象绑定到this上,叫做显式绑定var a = 0;function foo() {console.log(this.a);}var obj = {a: 2}foo(); //0foo.call(obj); //2foo.apply(obj); //2var fn = foo.bind(obj);fn(); //2// 2、硬绑定,是显式绑定的一个变种,使得this不能再被改变var a = 0;function foo() {console.log(this.a);}var obj = {a: 2}var bar = function () {foo.call(obj);}bar(); //2setTimeout(bar, 1000); //2bar.call(window); //2// 3、数组的forEach(fn,对象)、map()、filter()、some()、every()var id = 'window';/* function fn(el) {console.log(el, this.id);} */var obj = {id: 'fn'}var arr = [1, 2, 3];// this 指向了 objarr.forEach(function (el, index) {console.log(el, index, this);}, obj)
4、new关键字绑定
function fn() {// 1、如果是new关键字来执行函数,相当于构造函数来实例化对象,那么内部的this指向了当前实例化的对象console.log(this);}var fn1 = new fn();console.log(fn1);// 2function fn2() {// this还是指向了当前的对象console.log(this);// 使用return来返回对象的时候,实例化出来的对象是当前的返回对象return {name: '张三'}}var fn2 = new fn2();console.log(fn2);// 3var person = {fav:function(){return this;}}var p = new person.fav();console.log(p,p === person); //fav,false// 实例化出来的对象内部的属性constructor属性指向了当前的构造函数console.log(p.constructor === person.fav); //true
5、隐式丢失this的5种情况
隐式丢失就是指被隐式绑定的函数丢失了绑定对象,从而默认绑定到了window,这种情况非常容易出错且又非常常见。
// 1、隐式丢失,函数别名var a = 0;function foo() {console.log(this.a);}var obj = {a: 1,foo: foo}// 把obj.foo()赋值给变量bar,造成隐式丢失的情况,因为只是把obj.foo赋值给了bar变量,// 而bar与obj毫无关系var bar = obj.foo;bar();// 2、参数传递var a = 0;function foo() {console.log(this.a);}function bar(fn) {fn();}var obj = {a: 1,foo: foo}// 把obj.foo当作参数传递到bar函数中,有隐式的函数赋值 fn=obj.foo,只是把foo函数赋值给了fn,而fn函数与obj对象毫无关系,所以当前foo函数内部的this指向了windowbar(obj.foo);// 3、内置函数,setTimeout()和setInterval()第一个参数的回调函数中的this,默认指向了window,跟第2种情况是类似的var a = 0;function foo() {console.log(this.a);}var obj = {a: 1,foo: foo}setTimeout(obj.foo, 1000);// 4、间接调用var a = 0;function foo() {console.log(this.a);}var obj = {a: 1,foo: foo}var p = { a: 2 };// 隐式绑定,函数当作对象的方法来使用,内部的this指向了objobj.foo(); //1// 将obj.foo函数对象赋值给了p.foo()函数,然后立即执行,相当于仅仅是foo()函数的立即调用,内部的this默认指向了window(p.foo = obj.foo)(); //0p.foo = obj.foop.foo(); //2// 5、其他情况,指向了window的特殊情况var a = 0;function foo() {console.log(this.a);}var obj = {a: 1,foo: foo}(obj.foo = obj.foo)(); //0(false || obj.foo)(); //0(1,obj.foo)(); //0
6、严格模式下的this指向
// 1、严格模式下,独立调用的函数内部的this指向了undefined
function fn(){'use strict'console.log(this);
}
fn();// 2、严格模式下,函数apply()和call()内部的this始终是他们的第一个参数
var color = 'red';
function showColor(){'use strict'console.log(this); //nullconsole.log(this.color); //报错
}
showColor.call(null);
7、总结
1、默认绑定
2、隐式绑定
3、显示绑定
4、new绑定
分别对应函数的四种调用:
-独立调用
-方法调用
-间接调用
call()、apply()、bind()
-构造函数调用
隐式丢失:
1、函数别名
2、函数当作参数传递
3、内置函数
4、间接调用
5、其他情况,指向了window的特殊情况
文章最后:更多精彩文章和资源,欢迎参观我的公众号:小笑残虹。
一文搞懂this指向相关推荐
- 一文搞懂 Python 的 import 机制
一.前言 希望能够让读者一文搞懂 Python 的 import 机制 1.什么是 import 机制? 通常来讲,在一段 Python 代码中去执行引用另一个模块中的代码,就需要使用 Python ...
- 一文搞懂 Cocos Creator 3.0 坐标转换原理
一文搞懂 Cocos Creator 3.0 坐标转换原理 屏幕坐标 UI 触点坐标 UI 多分辨率适配方案 UI 触点获取 不同坐标之间的转换 屏幕坐标与 3D 节点世界坐标互转 3D 节点之间的坐 ...
- 一文搞懂指针,指针的指针,悬浮指针,野指针
一文搞懂指针,指针的指针,悬浮指针,野指针 学习C语言过程中,指针的概念往往是重难点,伴随着时隐时显的*,令人头晕.实际上指针并非如此复杂,掌握最基础概念,有利于我们更深刻的理解指针. [百科概念] ...
- 都2021年了,再不学ES6你就out了 —— 一文搞懂ES6
JS干货分享 -- 一文搞懂ES6 导语:ES6是什么?用来做什么? 1. let 与 const 2. 解构赋值 3. 模板字符串 4. ES6 函数(升级后更爽) 5. Class类 6. Map ...
- 网络知识扫盲,一文搞懂 DNS
在找工作面试的过程中,面试官非常喜欢考察基础知识,除了数据结构与算法之外,网络知识也是一个非常重要的考察对象. 而网络知识,通常是很抽象,不容易理解的,有很多同学就在这里裁了跟头.为了更好地通过面试, ...
- 一文搞懂什么VR,什么是6Dof,欧拉角,四元数转视图矩阵
目录 一.什么是VR 二.什么是3Dof,6Dof, 9Dof 三.欧拉角(姿态角) 四.Android手机的欧拉角与坐标系 五.安卓坐标系转换欧拉角 六.根据姿态四元数求视图矩阵 一文搞懂什么VR, ...
- ES6学习——一文搞懂ES6
ES6学习--一文搞懂ES6 es6介绍 ES全称EcmaScript,是脚本语言的规范,而平时经常编写的EcmaScript的一种实现,所以ES新特性其实就是指JavaScript的新特性. 为什么 ...
- 一文搞懂RNN(循环神经网络)
基础篇|一文搞懂RNN(循环神经网络) https://mp.weixin.qq.com/s/va1gmavl2ZESgnM7biORQg 神经网络基础 神经网络可以当做是能够拟合任意函数的黑盒子,只 ...
- python语言语句快的标记是什么_一文搞懂Python程序语句
原标题:一文搞懂Python程序语句 程序流 Python 程序中常用的基本数据类型,包括: 内置的数值数据类型 Tuple 容器类型 String 容器类型 List 容器类型 自然的顺序是从页面或 ...
- 一文搞懂 Java 线程中断
转载自 一文搞懂 Java 线程中断 在之前的一文<如何"优雅"地终止一个线程>中详细说明了 stop 终止线程的坏处及如何优雅地终止线程,那么还有别的可以终止线程 ...
最新文章
- 51单片机c语言应用开发三位一体实战精讲 pdf 119网盘,51单片机C语言应用开发三位一体实战精讲.pdf...
- puppet kick 功能
- IBM如何拥抱Spark
- Java当中编码和解码(以及出现乱编码的原因)
- mysql 控制id复原_清空mysql表后,自增id复原
- 【2017年第1期】专题导读:大数据与信用评价系统
- SimpleDet: 一套简单通用的目标检测与物体识别框架
- Cesium学习系列汇总
- 漫天飞舞的蒲公英你是我的幸福吗
- 排名前5位的免费Java电子书
- Visio-Cisco-华为-IBM网络设备官方模板
- tp5利用mysql数据库去重
- EXE文件结构及读取方法 1
- C语言键盘各键对应的键值
- sif4j 字符串拼接和占位符的区别
- mysql数据库存储引擎
- 软件设计师上午真题及参考答案
- 关于如何关闭445端口
- Spring 教程(一)
- 远程主机强迫关闭了一个现有的连接。请高手解答?
热门文章
- 因数分解——Pollard' p-1 Pollard rho
- 在Excel中激活数据分析工具
- 【TODO】Java并发:@GuardedBy
- 力扣刷题 DAY_88 贪心
- 如何自建微信外卖平台_怎么做微信外卖小程序_微信外卖小程序创建图文教程...
- 怎么用计算机看亲戚关系,小米亲戚计算器怎么用?如何利用小米计算器查询亲戚关系...
- 基于51单片机的无线测温系统
- 85后创业家告诉你:如何通过微博实现年销售上亿
- 在树莓派上安装配置远程摄像头监控motion
- 马来西亚php怎么样,科学网—游马来西亚的几点感想 - 梁生的博文