javascript开发:ES5与ES6的“this”深入分析

JavaScript 中的类与继承:从 ES5 到 ES6 在 JavaScript 中,类(Class)是用于创建对象的蓝图或模板。类通过 class 关键字定义,并且可以包含构造函数(constructor)以及其他方法。构造函数是用于初始化新创建对象的特殊方法。类的引入使得 JavaScript 的面向对象编程更加直观和结构化。 阅读详情

ES6中新增了箭头函数这种语法,箭头函数以其简洁性和方便获取this的特性,俘获了大批粉丝儿

它也可能是面试中的宠儿, 我们关键要搞清楚 箭头函数和普通函数中的this

一针见血式总结:

普通函数中的this:

1. this总是代表它的直接调用者, 例如 obj.func ,那么func中的this就是obj

2.在默认情况(非严格模式下,未使用 'use strict'),没找到直接调用者,则this指的是 window

3.在严格模式下,没有直接调用者的函数中的this是 undefined

4.使用call,apply,bind(ES5新增)绑定的,this指的是 绑定的对象

箭头函数中的this

默认指向在定义它时,它所处的对象(宿主对象),而不是执行时的对象, 定义它的时候,可能环境是window

下面通过一些例子来研究一下 this的一些使用场景[ 使用最新版 chrome测试 ]


要整明白这些, 我们需要首先了解一下作用域链:

当在函数中使用一个变量的时候,首先在本函数内部查找该变量,如果找不到则找其父级函数,

最后直到window,全局变量默认挂载在window对象下


1.全局变量默认挂载在window对象下

  1. <script>
  2.  var aa = 2;
  3.  alert(window.aa);
  4.  (function () {
  5.    aa = 3;
  6.  })();
  7.  alert(window.aa);
  8. </script>

我们仅仅声明了一个全局变量aa,但是打印出window.aa却和aa保持一致,为什么呢?

眼见为实, 我们使用 console.dir(window) 打印 window对象看看


我们可以看到在window属性中,看到aa属性了;此外,函数也适用于此情况,全局函数也会挂在在window对象下

我们常见的window的属性和方法有: alert, location,document,parseInt,setTimeout,setInterval等,window的属性默认可以省略window前缀!

2.在普通函数中,this指向它的直接调用者;如果找不到直接调用者,则是window

我们来看一些例子

示例1:

  1. <script>
  2.  function test() {
  3.    console.log(this);
  4.  }
  5.  test();
  6. </script>

结果是: window 

原因: test()是一个全局函数,也就是说是挂在window对象下的,所以 test()等价于 window.test() ,所以此时的this是window

示例2:

  1. <script>
  2.  var obj = {
  3.    say: function () {
  4.      setTimeout(function () {
  5.        console.log(this)
  6.      });
  7.    }
  8.  }
  9.  obj.say();
  10. </script>

结果是: window

匿名函数,定时器中的函数,由于没有默认的宿主对象,所以默认this指向window

问题: 如果想要在setTimeout/setInterval中使用这个对象的this引用呢?

用一个 变量提前把正确的 this引用保存 起来, 我们通常使用that = this, 或者 _this = this来保存我们需要的this指针!

  1. <script>
  2.  var obj = {
  3.    func: function() {},
  4.    say: function () {
  5.      var that = this;   //此时的this就是obj对象
  6.      setTimeout(function () {
  7.        console.log(this)
  8.        that.func()
  9.      });
  10.    }
  11.  }
  12.  obj.say();
  13. </script>

我们也可以使用 func.bind(this) 给回调函数直接绑定宿主对象, bind绑定宿主对象后依然返回这个函数, 这是更优雅的做法

  1. <span style="font-family:Times New Roman;"><script>  
  2.   var obj = {  
  3.     func: function() {},  
  4.     say: function () {  
  5.        // 此时的this就是obj对象  
  6.       setTimeout(function () {  
  7.         console.log(this)  
  8.         this.func()  
  9.       }.bind(this));  
  10.     }  
  11.   }  
  12.   obj.say(); // obj  
  13. </script></span>  

示例3(改变自360面试题):

  1.  window.val = 1;
  2.  var obj = {
  3.    val: 2,
  4.    dbl: function () {
  5.      this.val *= 2;
  6.      val *= 2;
  7.      console.log(val);
  8.      console.log(this.val);
  9.    }
  10.  };
  11.  // 说出下面的输出结果
  12.  obj.dbl();
  13.  var func = obj.dbl;
  14.  func();

结果是:  2   4    8   8

<1> 12行代码调用

val变量在没有指定对象前缀,默认从函数中找,找不到则从window中找全局变量

即 val *=2 就是 window.val *= 2

this.val默认指的是 obj.val ;因为 dbl()第一次被obj直接调用

<2>14行代码调用

func() 没有任何前缀,类似于全局函数,即  window.func调用,所以

第二次调用的时候, this指的是window, val指的是window.val

第二次的结果受第一次的影响

3.在严格模式下的this

  1. <script>
  2.  function test() {
  3.    'use strict';
  4.    console.log(this);
  5.  }
  6.  test();
  7. </script>

结果是: undefined

4.箭头函数中的 this

  1. <script>
  2.  var obj = {
  3.    say: function () {
  4.      setTimeout(() => {
  5.        console.log(this)
  6.      });
  7.    }
  8.  }
  9.  obj.say(); // obj
  10. </script>

此时的 this指的是定义它的对象, obj,而不是 window!

示例(多层嵌套的箭头函数):

  1. <script>
  2. var obj = {
  3. say: function () {
  4. var f1 = () => {
  5. console.log(this); // obj
  6. setTimeout(() => {
  7. console.log(this); // obj
  8. })
  9. }
  10. f1();
  11. }
  12. }
  13. obj.say()
  14. </script>

因为f1定义时所处的函数 中的 this是指的 obj, 所以不管有多层嵌套,都是 obj

示例(复杂情况: 普通函数和箭头函数混杂嵌套)

  1. <script>
  2. var obj = {
  3. say: function () {
  4. var f1 = function () {
  5. console.log(this); // window, f1调用时,没有宿主对象,默认是window
  6. setTimeout(() => {
  7. console.log(this); // window
  8. })
  9. };
  10. f1();
  11. }
  12. }
  13. obj.say()
  14. </script>
结果: 都是 window,因为 箭头函数在定义的时候它所处的环境相当于是window, 所以在箭头函数内部的this函数window

示例(严格模式下的混杂嵌套)

  1. <script>
  2. var obj = {
  3. say: function () {
  4. 'use strict';
  5. var f1 = function () {
  6. console.log(this); // undefined
  7. setTimeout(() => {
  8. console.log(this); // undefined
  9. })
  10. };
  11. f1();
  12. }
  13. }
  14. obj.say()
  15. </script>

结果都是undefined

说明: 严格模式下,没有宿主调用的函数中的this是undefined!!!所以箭头函数中的也是undefined!

JavaScript【ES5、ES6】版本写法对照表 //React/React Native 的ES5 ES6写法对照表 // //很多React/React Native的初学者都被ES6的问题迷惑:各路大神都建议我们直接学习ES6的语法(class Foo extends React.Component),然而网上搜到的很多教程和例子都是ES5版本的,所以很多人在学习的时候连照猫画虎都不知道怎么做。今天在此整理了一些ES5和ES6的写法对照 阅读详情

相关推荐

JavaScript高级——ES6基础入门

前言ES6(ECMAScript 6),也被称为ES2015,是JavaScript的第六个版本.它于2015年发布,并在现代JavaScript开发中扮演了重要的角色.学习方法:看千遍,不如自己动手写一遍遇到问题不要怕,微笑着面对它记笔记let 和 constconst和let是在ES6中引入的两个新的变量声明关键字,用于声明变量的作用域。const:const用于声明一个常量,其值在声明后不能被修改。常量必须在声明时进行初始化,而且不能再次赋值。

z16638522031的博客 1270

call,apply,bind指定函数的this指向详解,功能细节,严格和非严格模式下设定this指向

call,apply,bind指定函数的this指向详解,功能细节,严格和非严格模式下设定this指向

阿牛哥的博客 480

详解JavaScript中ES5和ES6的类、继承之间区别和联系

导读: 很多JavaScript的初学者(比如说我)在刚开始学习这门语言的时候,往往会对函数、对象、类、继承这些概念感到迷茫和疑惑,感觉他们彼此之间长得十分相似,这就导致很难分清他们什么时候该怎么用。特别是JavaScript中有了原型这个概念之后,就觉得更加混乱了。本篇文章我就从一个初学者的角度身份来去梳理一下这些概念和用法之间的区别与联系,力图能让同样是初学者的你很好的分清这些概念之间的用法。 ES5中类、对象和原型 ES5没有真正定义类的关键字,它通过函数首字母大写的方式来告诉别人这是一个类,..

Einstellung的博客 2136

深入理解ES6箭头函数的this

ES6中新增了箭头函数这种语法,箭头函数以其简洁性和方便获取this的特性,俘获了大批粉丝儿 它也可能是面试中的宠儿, 我们关键要搞清楚 箭头函数和普通函数中的this 一针见血式总结: 普通函数中的this: 1. this总是代表它的直接调用者, 例如 obj.func ,那么func中的this就是obj 2.在默认情况(非严格模式下,未使用 'use stri

梦颖飞燕--博客 680

JS用ES6和ES5分别实现:8字节长整数和字节数组的互转

JavaScript作为Web开发的通用语言,在物联网边缘计算、Node.js服务端等场景的应用日益广泛。但由于其动态类型和数值精度的特殊性,处理二进制数据时面临独特挑战: 精度局限:JS的Number类型采用IEEE 754双精度浮点格式,仅能安全表示±253±253范围内的整数,超出范围将丢失精度 字节序控制:现代CPU架构多采用小端序,而网络协议通常要求大端序,需要显式控制字节排列 类型差异:Java/C#等语言的byte类型为有符号数(-128 至127),而JS的Type

在技术的广袤天地里,本博客如精准罗盘。剖析前沿科技,深掘代码奥秘,以精炼笔触,带您穿越复杂技术迷宫,速达知识彼岸。 2239

从零到一:FAST_LIO与FAST_LIO2算法环境搭建与实战评测

本文详细介绍了FAST_LIO与FAST_LIO2算法的环境搭建与实战评测,包括算法原理、环境配置避坑指南、源码编译技巧及性能对比。FAST_LIO2凭借ikd-tree数据结构在动态环境中表现优异,处理速度提升至15ms,内存占用降低40%。文章还提供了常见问题排查和进阶优化技巧,助力开发者高效实现SLAM应用。

weixin_29271053的博客 470

this指向问题call、apply、bind超详细

例子中,obj的A/B函数都是返回一个内部定义的函数,A、B内部定义的函数函数返回值都是this,只是在A中,内部函数是箭头函数,而B中则是普通函数。将A、B函数创建的内部函数分别赋值给变量func进行调用,未指定调用者,可以发现箭头函数的返回值this能够指向obj,而普通函数的this则因为未指定调用者而指向了全局对象。箭头函数的this取决于函数定义所在的上下文中this,即函数定义外部this是什么,箭头函数内部的this就是什么,相当于固化了当前执行环境中的this,注意不是函数定义所在的对象!

weixin_52901235的博客 848

工业4.0 底层逻辑

工业4.0 的概念已经被滥用了,它与物联网,工业物联网等概念一样,几乎什么都往里面装。演变成了一句口号和愿景。许多人并不清楚工业4.0的底层逻辑到底是什么?如何遵循工业4.0 的思想构建新一代智能制造系统?并没用清晰地展示工业4.0的技术路线图。

姚家湾博客 1993

重写apply()方法

var obj = { a: 'xiao', b: 'hong' } function test(){ console.log(this, arguments); } Function.prototype.myApply = function(ctx, args){ var ctx = ctx ? Object(ctx) : window; ctx.originFn = this; //如果不是object && fn , 证明时原始值抛出异常 if

qq_44738564的博客 478

固定翼飞行器建模(二)——MATLAB/Simulink建模、配平及线性化

MATLAB/Simulink固定翼建模、配平及线性化。

2302_80148937的博客 1万+

双足步行机器人的ZMP与CoP检测

静态步行与动态步行   机器人步态分为静态步行和动态步行。当机器人做静态步行运动时,身体的各个部分运动速度很小,机器人的整体稳定性较易控制。静态步行稳定性采用机器人的重心地面投影点(Center of Gravity,简称CoG)作为稳定性标准,这种判定方法适用于运动较为缓慢的情况。如果机器人采用的是一种高速运动的步行方式,则称之为动态步行。当机器人进行动态步行时,其重心的位置和加速度的大小时...

weixin_34112208的博客 5907

通过call、apply、bind去改变函数的this指向以及this指向详解

一、this指向详解 this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象(这句话不那么严谨,作为一般情况下是可以的) 再加下面的补充,就完美啦: 情况1:如果一个函数中有this,但是它没有被上一级的对象所调用,那么this指向的就是window,这里需要说明的是在js的严格版中this指向的不是window,但是我们这里不探讨严格版的问题(在严格版中的默认的this不再是window,而是undefined。)

小福气的博客 665

保姆级教程:用PCAN-View监控汽车CAN总线,从硬件连接到报文分析(附快捷键大全)

本文提供了一份详细的PCAN-View使用教程,涵盖从硬件连接到报文分析的全流程,特别适合汽车电子工程师和初学者。内容包括硬件准备、软件安装、核心功能操作、高级技巧及故障排查,并附有实用的快捷键大全,帮助用户高效监控和分析CAN总线数据。

weixin_42542669的博客 497

从脚本到工程化:ES5 与 ES6 重塑 JavaScript 的十年

JavaScript经历了从ES5到ES6的重大变革:ES5(2009)为JS建立了基本规范,引入严格模式、数组方法、JSON支持等基础功能,使其从松散脚本迈向工程化雏形;而ES6(2015)则带来let/const、模块化、箭头函数等现代化特性,彻底解决了作用域、异步编程等核心问题。两个版本共同塑造了现代JavaScript——ES5奠定基础规范,ES6提供工程化能力,使JS从简单的网页脚本进化为支持大型应用开发的成熟语言。如今ES6已成为前端开发标配,但其核心思想仍建立在ES5的基础之上。

qq_43548436的博客 1171

直播间人气协议算法:从批量操作到数据接口的自动化实现

本文深入解析直播间人气协议算法的实现原理与技术细节,涵盖批量账号管理、IP代理方案、用户行为模拟算法及平台数据接口调用策略。通过逆向工程分析通信协议,结合算法设计实现自动化流量提升,同时探讨风控规避与系统性能优化方案,为开发者提供合规的技术实践参考。

weixin_30505225的博客 517

面向边缘计算的YOLOv12模型剪枝-蒸馏联合优化实战教程**

这套剪枝-蒸馏联合方案的优势在于其系统性和可靠性。它不是单一的技巧,而是一套完整的工程流程,确保了从研发到部署的无缝衔接。

FJN110的博客 158

ES5 vs ES6:JavaScript 演进之路

ES5 vs ES6:JavaScript 演进之路

qq_20236937的博客 1803

SAP 权限配置(复合角色)

复合角色创建步骤:业务场景:通常单一角色权限颗粒度划分比较细,当需要分配单一角色权限A、B(多个单一角色)给某账号用户Y时,可以先建立一个复合角色C,将A、B绑定到复合角色C中,再将角色C分配给账号Y即完成权限配置。 业务模拟: 1、PFCG创建复合角色: 2、在角色页面添加子角色 在角色分页内添加子角色,点击“菜单”分页中的“读菜单”即可导入子角色中的菜单: 3、将用户分配给...

willieyuan的博客 7087

ES6与JavaScript之间的关系

js与node.js JS是由ES(ECMAScript)、DOM(浏览器文档对象)、BOM(浏览器对象模型)组成。 其中Node.Js就只有ES,目前浏览器比较流行的版本就是ES6(ES2015),老浏览器的版本基本上都是ES5。所以alert和document不能在Node运行(因为Node没有dom和bom)。 ECMAScript 6简介 ECMAScript 6.0(以下简称ES6)是J...

qq_43542074的博客 5601

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

【JS笔记】JavaScript语法快速上手— ES5和ES6(五)

【JS笔记】JavaScript语法 快速上手— ES5和ES6(五)

leo的博客 991

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

从ES5到ES6+:JavaScript语法演进与实现解析

本文探讨了JavaScript从ES5到ES6+的语法演进,重点介绍了ES6+中的新特性及其在ES5中的实现方式。ES6+引入了let和const、箭头函数、解构赋值、模板字符串和类等语法糖,显著提升了代码的简洁性和可维护性。文章还分析了这些新特性在ES5中的模拟实现,帮助开发者理解其底层机制。ES6+的推出不仅改进了语法,还推动了模块化、异步编程等现代开发模式的应用,标志着JavaScript语言的一次重要跃迁。

qq_64546210的博客 1384

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

深入浅出:JavaScript ES6中类(Class)的革新与实践

在JavaScript的发展历程中,ES6(ECMAScript 2015)无疑是一个里程碑式的版本。它不仅引入了`let`、`const`、箭头函数等特性,更通过**类(Class)**的语法革新,彻底改变了开发者对面向对象编程的理解与实践。本文将带你深入浅出地了解ES6类的核心功能,从定义到特点,再到与传统方法的对比,最后总结关键注意事项,帮助你在实际开发中游刃有余。

JakeMa1024的博客 1775

ES5与ES6继承的区别

1.ES5的继承实质上是先创建子类的实例对象,然后再将父类的方法添加到this上(Parent.apply(this)). 2.ES6的继承机制完全不同,实质上是先创建父类的实例对象this(所以必须先调用父类的super()方法),然后再用子类的构造函数修改this。 3.ES5的继承时通过原型或构造函数机制来实现。 4.ES6通过class关键字定义类,里面有构造方法,类之间通过extends...

qq_42908794的博客 1万+

ES5与ES6的对比不同点

很多React/React Native的初学者都被ES6的问题迷惑:各路大神都建议我们直接学习ES6的语法(class Foo extends React.Component),然而网上搜到的很多教程和例子都是ES5版本的,所以很多人在学习的时候连照猫画虎都不知道怎么做。今天在此整理了一些ES5和ES6的写法对照表,希望大家以后读到ES5的代码,也能通过对照,在ES6下实现相同的功能。

chanzhu的博客 1万+

JavaScript 与 ES5 与 ES6 与 Node.js 之间的关系

参考自:https://es6.ruanyifeng.com/#docs/intro JavaScript 由Netscape 公司创造,1996 年 11 月,决定将 JavaScript 提交给标准化组织 ECMA,希望这种语言能够成为国际标准。之后,由ECMA发布的JavaScript就叫做ECMAScript了,简称ES。 1、ECMAScript 和 JavaScript 的关系 ECMAScript 和 JavaScript 的关系是,前者是后者的规格,后者是前者的一种实现。 2、ES.

青蛙king的博客 1089

JavaScript ES5 vs ES6 核心特性对比

ES6(ECMAScript 2015)引入了大量现代化语法和新特性,使 JavaScript 更加简洁、易读、易维护。以下是 ES5 与 ES6 的核心特性详细对比。特性ES5ES6变量声明var(函数作用域)letconst(块级作用域)函数function声明箭头函数、默认参数、剩余参数字符串拼接、转义模板字符串、插值、多行对象完整写法属性简写、方法简写、计算属性数组mapfilterreducefindincludesArray.from、扩展运算符异步回调函数Promise(后续)

csdn_silent的博客 1350
上一篇: javascript开发:AMD与CMD的本质区别分析
下一篇: vue开发:详解vue.js的devtools安装
Generon
博客等级 码龄11年 135粉丝 135原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值