深入理解JS:执行上下文中的this(二)
目录
- 序言
- Function.prototype.bind() 方法
- 箭头函数
- 参考
1.序言
在 深入理解JS:执行上下文中的this(一) 中,我们主要深入分析全局环境和函数环境中函数调用的 this,还留下 bind 方法以及箭头函数的 this 尚未分析,因此我们将在这篇文章进行讲解。
2.Function.prototype.bind() 方法
bind() 方法将会创建返回一个新的函数。在 bind() 被调用时,这个新函数的 this 将被指定为 bind() 的第一个参数,而其余参数将作为新函数的参数,供调用时使用。
ES5 引入了 bind 方法来设置函数的 this 值,而不用考虑函数如何被调用的。
这里给出一种 bind() 的实现算法:
var slice = Array.prototype.slice;
Function.prototype.bind = function() {
var thatFunc = this, thatArg = arguments[0];
var args = slice.call(arguments, 1);
if (typeof thatFunc !== 'function') {
throw new TypeError('Function.prototype.bind called on incompatible ' + thatFunc);
}
return function(){
var funcArgs = args.concat(slice.call(arguments))
return thatFunc.apply(thatArg, funcArgs);
};
};
注:上述代码并没有完全按照ES5规范实现,只是作为一种实现参考,更加完善的解决方案可以参考 function-bind
但不论哪种实现,其实质上都是通过使用类似 Function.prototype.apply(thisArg, argArray) 方法来实现指定调用函数 this 的。
3.箭头函数
箭头函数表达式的语法比函数表达式更简洁,并且没有自己的 this,arguments,super 或 new.target。它很适合用作匿名函数,并且不能用作构造函数(为什么呢?详情点击查看)。
ES6 引入了支持 this 词法解析的箭头函数(它在闭合的执行环境内设置 this 的值)。
如何理解箭头函数在闭合的执行环境内设置 this 的值?
简单理解,箭头函数不会创建自己的 this,它的 this 与封闭词法环境的 this 保持一致,即如果箭头函数在全局环境中,那么它的 this 就指向全局对象,如果箭头函数在某一个函数中,那么它的 this 就指向所在函数的 this。
我们来看几个示例:
(1)全局环境
var global = this
var foo = () => { return this }
var value = 1
var bar = {
value: 2,
getValueByArrowFunc: () => {
return this.value
},
getValue: function (){
return this.value
},
}
console.log(foo() === global) // true
// 箭头函数 this => global
console.log(bar.getValueByArrowFunc()) // 1
// 普通函数 this => bar
console.log(bar.getValue()) // 2
(2)函数环境
ES6的语法:
function foo() {
this.value = 1
// 箭头函数表达式
var arr = () => {
console.log(this.value)
}
arr()
}
转化为ES5:
function foo() {
var _this = this;
this.value = 1;
// 转化为普通函数表达式
var arr = function arr() {
console.log(_this.value);
};
arr();
}
对比转化前后的代码可以看出:箭头函数会转化为一个普通函数,通过一个临时变量 _this 来传递,它之前的 this 就是所在函数的 this
(3)call() 、 apply() 或 bind() 方法
var global = this
var foo = {
bar: () => {
return this
}
}
var obj = { value : 1 }
console.log(foo.bar() === global) // true
console.log(foo.bar.call(obj) === global) // true
console.log(foo.bar.apply(obj) === global) // true
var bind = foo.bar.bind(obj)
console.log(bind() === global) // true
由于箭头函数不会创建自己的 this,那么通过 call() 、 apply() 或 bind() 方法调用一个箭头函数时,只能传递参数,第一个参数会被忽略。
4.参考
this 关键字 - JavaScript | MDN - Mozilla
Function.prototype.bind() - JavaScript - MDN - Mozilla
深入理解JS:执行上下文中的this(二)的更多相关文章
- 从一道看似简单的面试题重新理解JS执行机制与定时器
壹 ❀ 引 最近在看前端进阶的系列专栏,碰巧看到了几篇关于JS事件执行机制的面试文章,因为我在之前一篇 JS执行机制详解,定时器时间间隔的真正含义 博文中也有记录JS执行机制,所以正好用于作为测试自 ...
- 深入理解JS 执行细节
javascript从定义到执行,JS引擎在实现层做了很多初始化工作,因此在学习JS引擎工作机制之前,我们需要引入几个相关的概念:执行环境栈.全局对象.执行环境.变量对象.活动对象.作用域和作用域链等 ...
- 深入理解JS执行细节(写的很精辟)
来源于:http://www.cnblogs.com/onepixel/p/5090799.html javascript从定义到执行,JS引擎在实现层做了很多初始化工作,因此在学习JS引擎工作机制之 ...
- 深入理解js——执行上下文
什么是"执行上下文"?暂且不下定义,先看一段代码: 第一句报错,a未定义,很正常.第二句.第三句输出都是undefined,说明浏览器在执行console.log(a)时,已经知道 ...
- 深入学习JS执行--创建执行上下文(变量对象,作用域链,this)
一.介绍 本篇继上一篇深入理解js执行--单线程的JS,这次我们来深入了解js执行过程中的执行上下文. 本篇涉及到的名词:预执行,执行上下文,变量对象,活动对象,作用域链,this等 二.预执行 在上 ...
- JS执行机制详解,定时器时间间隔的真正含义
壹 ❀ 引 通过结果倒推过程是我们常用的思考模式,我在上一篇学习promise笔记中,有少量关于promise执行顺序的例子,通过倒推,我成功让自己对于js执行机制的理解一塌糊涂,js事件机制,事件 ...
- 深入理解JS:执行上下文中的this(一)
目录 执行上下文与执行上下文栈 this 全局环境 函数环境 总结 参考 1.执行上下文与执行上下文栈 (1)什么是执行上下文? 在 JavaScript 代码运行时,解释执行全局代码.调用函数或使用 ...
- js的基础(平民理解的执行上下文/调用堆栈/内存栈/值类型/引用类型)
与以前的切图比较,现在的前端开发对js的要求似乎越来越高,在开发中,我们不仅仅是要知道如何运用现有的框架(react/vue/ng), 而且我们对一些基础的知识的依赖越来越大. 现在我们就用平民的方法 ...
- 10分钟理解JS引擎的执行机制
首先,请牢记2点: (1) JS是单线程语言 (2) JS的Event Loop是JS的执行机制.深入了解JS的执行,就等于深入了解JS里的event loop 1.灵魂三问 (1) JS为什么是单线 ...
随机推荐
- windows下遍历文件夹
Github地址 函数: HANDLE WINAPI FindFirstFile( _In_ LPCTSTR lpFileName, _Out_ LPWIN32_FIND_DATA lpFindFil ...
- 数据库SQL语言从入门到精通--Part 1--SQL语言概述
数据库从入门到精通合集(超详细,学习数据库必看) 一.SQL概述 关系数据库标准语言SQL(结构化查询语言). 结构化查询语言(Structured Query Language)简称SQL,是一种特 ...
- CF--思维练习--CodeForces - 219C Color Stripe (思维)
ACM思维题训练集合 A colored stripe is represented by a horizontal row of n square cells, each cell is paine ...
- CF #636 (Div. 3) 对应题号CF1343
unrated 选手悠闲做题,然后只做出四个滚蛋了 符合 div3 一贯风格,没啥难算法 E最后就要调出来了,但还是赛后才A的 CF1343A Candies 传送门 找到一个 \(x\),使得存在一 ...
- 深度优先搜索理论基础与实践(java)
概论 深度优先搜索属于图算法的一种,是一个针对图和树的遍历算法,英文缩写为 DFS 即 Depth First Search.深度优先搜索是图论中的经典算法,利用深度优先搜索算法可以产生目标图的相应拓 ...
- 最短路径树:Dijstra算法
一.背景 全文根据<算法-第四版>,Dijkstra算法.我们把问题抽象为2步:1.数据结构抽象 2.实现 二.算法分析 2.1 数据结构 顶点+边->图.注意:Dijkstra ...
- [js进阶1]-数据类型
基本数据类型 js 总的有7中数据类型,包括基本类型和引用类型 基本类型 6 种 number boolean string null undefiend symbol 前5种类型统称为原始类型 sy ...
- 【Kafka】配置文件说明
目录 server.properties producer.properties consumer.properties server.properties # broker的全局唯一编号,不能重复 ...
- iOS中的事件响应链、单例模式、工厂模式、观察者模式
学习内容 欢迎关注我的iOS学习总结--每天学一点iOS:https://github.com/practiceqian/one-day-one-iOS-summary iOS中事件传递和相应机制 i ...
- 一文带你学会国产加密算法SM4的vue实现方案
前言 上篇文章我们介绍了国产SM4加密算法的后端java实现方案.没有看过的小伙伴可以看一下这篇文章. https://www.cnblogs.com/jichi/p/12907453.html 本篇 ...