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指向相关推荐

  1. 一文搞懂 Python 的 import 机制

    一.前言 希望能够让读者一文搞懂 Python 的 import 机制 1.什么是 import 机制? 通常来讲,在一段 Python 代码中去执行引用另一个模块中的代码,就需要使用 Python ...

  2. 一文搞懂 Cocos Creator 3.0 坐标转换原理

    一文搞懂 Cocos Creator 3.0 坐标转换原理 屏幕坐标 UI 触点坐标 UI 多分辨率适配方案 UI 触点获取 不同坐标之间的转换 屏幕坐标与 3D 节点世界坐标互转 3D 节点之间的坐 ...

  3. 一文搞懂指针,指针的指针,悬浮指针,野指针

    一文搞懂指针,指针的指针,悬浮指针,野指针 学习C语言过程中,指针的概念往往是重难点,伴随着时隐时显的*,令人头晕.实际上指针并非如此复杂,掌握最基础概念,有利于我们更深刻的理解指针. [百科概念] ...

  4. 都2021年了,再不学ES6你就out了 —— 一文搞懂ES6

    JS干货分享 -- 一文搞懂ES6 导语:ES6是什么?用来做什么? 1. let 与 const 2. 解构赋值 3. 模板字符串 4. ES6 函数(升级后更爽) 5. Class类 6. Map ...

  5. 网络知识扫盲,一文搞懂 DNS

    在找工作面试的过程中,面试官非常喜欢考察基础知识,除了数据结构与算法之外,网络知识也是一个非常重要的考察对象. 而网络知识,通常是很抽象,不容易理解的,有很多同学就在这里裁了跟头.为了更好地通过面试, ...

  6. 一文搞懂什么VR,什么是6Dof,欧拉角,四元数转视图矩阵

    目录 一.什么是VR 二.什么是3Dof,6Dof, 9Dof 三.欧拉角(姿态角) 四.Android手机的欧拉角与坐标系 五.安卓坐标系转换欧拉角 六.根据姿态四元数求视图矩阵 一文搞懂什么VR, ...

  7. ES6学习——一文搞懂ES6

    ES6学习--一文搞懂ES6 es6介绍 ES全称EcmaScript,是脚本语言的规范,而平时经常编写的EcmaScript的一种实现,所以ES新特性其实就是指JavaScript的新特性. 为什么 ...

  8. 一文搞懂RNN(循环神经网络)

    基础篇|一文搞懂RNN(循环神经网络) https://mp.weixin.qq.com/s/va1gmavl2ZESgnM7biORQg 神经网络基础 神经网络可以当做是能够拟合任意函数的黑盒子,只 ...

  9. python语言语句快的标记是什么_一文搞懂Python程序语句

    原标题:一文搞懂Python程序语句 程序流 Python 程序中常用的基本数据类型,包括: 内置的数值数据类型 Tuple 容器类型 String 容器类型 List 容器类型 自然的顺序是从页面或 ...

  10. 一文搞懂 Java 线程中断

    转载自   一文搞懂 Java 线程中断 在之前的一文<如何"优雅"地终止一个线程>中详细说明了 stop 终止线程的坏处及如何优雅地终止线程,那么还有别的可以终止线程 ...

最新文章

  1. 51单片机c语言应用开发三位一体实战精讲 pdf 119网盘,51单片机C语言应用开发三位一体实战精讲.pdf...
  2. puppet kick 功能
  3. IBM如何拥抱Spark
  4. Java当中编码和解码(以及出现乱编码的原因)
  5. mysql 控制id复原_清空mysql表后,自增id复原
  6. 【2017年第1期】专题导读:大数据与信用评价系统
  7. SimpleDet: 一套简单通用的目标检测与物体识别框架
  8. Cesium学习系列汇总
  9. 漫天飞舞的蒲公英你是我的幸福吗
  10. 排名前5位的免费Java电子书
  11. Visio-Cisco-华为-IBM网络设备官方模板
  12. tp5利用mysql数据库去重
  13. EXE文件结构及读取方法 1
  14. C语言键盘各键对应的键值
  15. sif4j 字符串拼接和占位符的区别
  16. mysql数据库存储引擎
  17. 软件设计师上午真题及参考答案
  18. 关于如何关闭445端口
  19. Spring 教程(一)
  20. 远程主机强迫关闭了一个现有的连接。请高手解答?

热门文章

  1. 因数分解——Pollard' p-1 Pollard rho
  2. 在Excel中激活数据分析工具
  3. 【TODO】Java并发:@GuardedBy
  4. 力扣刷题 DAY_88 贪心
  5. 如何自建微信外卖平台_怎么做微信外卖小程序_微信外卖小程序创建图文教程...
  6. 怎么用计算机看亲戚关系,小米亲戚计算器怎么用?如何利用小米计算器查询亲戚关系...
  7. 基于51单片机的无线测温系统
  8. 85后创业家告诉你:如何通过微博实现年销售上亿
  9. 在树莓派上安装配置远程摄像头监控motion
  10. 马来西亚php怎么样,科学网—游马来西亚的几点感想 - 梁生的博文