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

两个独立的正态分布的和仍然为正态分布的证明

正态分布的和

weixin_40064300的博客 1万+

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

DCDC--控制方式(Control Mode)

DCDC反馈控制方式

网始如芯个人博客 1万+

重写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

Unity多渠道APK打包:同一工程稳定输出不冲突安装包

Android应用多渠道分发是移动开发的基础场景,其核心在于解决包名唯一性、渠道可识别性与构建可重复性三大问题。原理上,Unity安卓打包本质是三阶段流程:生成Android工程、Gradle编译、APK签名,而包名冲突根源在生成阶段对PlayerSettings的强依赖。技术价值体现在规避人工配置失误、支撑CI/CD自动化、满足华为/小米等商店合规要求。典型应用场景包括应用宝、TapTap、B站等渠道独立包管理,以及AB测试、灰度发布等运营需求。本文聚焦Unity原生方案,通过BuildPlayerOpt

weixin_33736048的博客 794

《LabVIEW ZYNQ实战指南》第6章>>案例解析:基于USB WiFi模块的ZYNQ无线通信部署与Linux RT开发

本文详细解析了如何为ZYNQ开发板部署USB WiFi模块,实现无线通信。通过LabVIEW Linux RT环境,利用封装好的驱动VI,开发者可轻松配置ZYNQ连接无线网络,摆脱网线束缚,实现程序无线部署与远程调试,为工业物联网应用奠定基础。

app77的博客 755

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

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

小福气的博客 665

脑电分析:为什么大脑信号会“变同步”?——事件相关同步化与去同步化 (ERS/ERD) 全景解析

脑电分析中的事件相关同步化(ERS)和去同步化(ERD)是研究大脑动态节律的重要方法,反映特定任务下脑电频段能量的变化。ERD表示神经元活动分散(功率下降),提示脑区活跃处理信息;ERS则反映神经元同步(功率增强),常与静息状态相关。本文详解了ERS/ERD的生理机制、计算流程(包括基线校正和功率谱分析),并提供了Python实现示例,展示如何通过Welch法和STFT进行时频分析,生成ERD/ERS热力图。该技术广泛应用于运动想象脑机接口、癫痫检测等领域,为理解大脑功能状态提供了量化工具。

qq_32516809的博客 1395

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

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

qq_43548436的博客 1171

【EPS精品教程】EPS2016三维测图版安装教程(附EPS2016安装包下载地址)

EPS地理信息工作站是北京清华山维新技术开发有限公司历经十五年精心研发和打造,为满足“以地理信息服务为中心”的信息化测绘生产需求而推出的测绘生产活动多种业务模块集成化软件系统。主要功能有:(1)测绘与地理信息多业务模块集成管理;(2)多元多尺度多种类数据集成管理;(3)跨平台异构数据转换;(4)数据监理;(5)自动缩编与综合;(6)坐标转换与动态投影;(7)地理信息模板定制;(8)GIS地理信息描述与CAD图形表达一体化支持;(9)GIS数据库更新维护;(10)图形打印与地图出版。 一、安装过程 EP..

智慧空间实验室 2万+

详解AUTOSAR:专栏总述

本专栏系统介绍AUTOSAR规范及车用控制器软件开发,内容覆盖基础架构、SWC/RTE、通信栈、诊断、存储、安全、看门狗、工具链、环境配置与项目实战,并持续更新各模块的集成机制与工程要点。

不脱发的程序猿 3923

ES5 vs ES6:JavaScript 演进之路

ES5 vs ES6:JavaScript 演进之路

qq_20236937的博客 1803

Android11.0(R) MTK 平台开机logo动态替换(by logo.bin方式)

实现的效果 客户提供一张格式为 bmp 的开机logo,在 linux 环境下执行制作 logo.bin 脚本文件, apk 拷贝 logo.bin 文件替换系统原有的bin,然后重启 logo 自动更新。 原理分析 MTK 平台的充电图片和开机logo都是打包到 logo.bin 中的 对应的资源路径在源码 vendor\mediatek\proprietary\bootable\bootloader\lk\dev\logo 系统一般预制了很多分辨率文件夹,实际通过 BOOT_LOGO 来确定打包那一个

cczhengv 4585

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

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

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

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

leo的博客 991

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

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

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

qq_64546210的博客 1384

深入浅出: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、付费专栏及课程。

余额充值