深入理解this机制系列第三篇——箭头函数
前面的话
this机制与函数调用有关,而作用域则与函数定义有关。有没有什么是可以将this机制和作用域联系起来的呢?本文将介绍ES6新增的内容——箭头函数
痛点
对于闭包的痛点在于,闭包的this默认绑定到window对象,但又常常需要访问嵌套函数的this,所以常常在嵌套函数中使用var that = this,然后在闭包中使用that替代this,使用作用域查找的方法来找到嵌套函数的this值
var a = 0;
function foo(){
function test(){
console.log(this.a);
}
return test;
};
var obj = {
a : 2,
foo:foo
}
obj.foo()();//
var a = 0;
function foo(){
var that = this;
function test(){
console.log(that.a);
}
return test;
};
var obj = {
a : 2,
foo:foo
}
obj.foo()();//
解决
而箭头函数的出现就可以很好的解决该问题。箭头函数根据当前的词法作用域而不是根据this机制顺序来决定this,所以,箭头函数会继承外层函数调用的this绑定,而无论this绑定到什么
var test = () => {
console.log(this.a);
}
//形式上等价于
var test = function(){
console.log(this.a);
}
//实质上等价于
function fn(){
var that = this;
var test = function(){
console.log(that.a);
}
}
var a = 0;
function foo(){
var test = () => {
console.log(this.a);
}
return test;
};
var obj = {
a : 2,
foo:foo
}
obj.foo()();//
基本用法
ES6允许使用“箭头”(=>)定义函数,一般称为胖箭头
var f = v => v;
console.log(f(1));//
//等同于
var f = function(v) {
return v;
};
console.log(f(1));//
如果箭头函数不需要参数或需要多个参数,就使用一个圆括号代表参数部分
var f = () => 5;
// 等同于
var f = function () { return 5 }; var sum = (num1, num2) => num1 + num2;
// 等同于
var sum = function(num1, num2) {
return num1 + num2;
};
如果箭头函数的代码块部分多于一条语句,就要使用大括号将它们括起来
var sum = (num1, num2) => {
var restult = num1 + num2;
return result;
}
由于大括号被解释为代码块,所以如果箭头函数直接返回一个对象,必须在对象外面加上括号
var getTempItem = id => ({ id: id, name: "Temp" });
回调函数
箭头函数最常用于回调函数,如事件处理器或定时器中
function foo() {
setTimeout(() => {
console.log( this.a );
},100);
}
var obj = {
a: 2
};
foo.call( obj ); //
//等价于
function foo() {
var that = this;
setTimeout( function(){
console.log( that.a );
}, 100 );
}
var obj = {
a: 2
};
foo.call( obj ); //
注意事项
【1】this在箭头函数中被绑定,4种绑定规则中的无论哪种都无法改变其绑定
var a = 0;
function foo(){
var test = () => {
console.log(this.a);
}
return test;
};
var obj1 = {
a : 1,
foo:foo
}
var obj2 = {
a : 2,
foo:foo
}
obj1.foo()();//
var bar = foo.call(obj1);
//由于上一条语句已经把this绑定到obj1上,且无法修改。所以本条语句call(obj2)无效,返回的值是obj1.a的值1
bar.call(obj2);//
【2】箭头函数不可以当作构造函数,也就是不可以使用new命令,否则会报错
var foo = () =>{return 1;}
foo();//
var obj = new foo();//Uncaught TypeError: foo is not a constructor
【3】箭头函数中不存在arguments对象
var foo = () =>{
console.log(arguments);//Uncaught ReferenceError: arguments is not defined
return 1;
}
foo();
最后
虽然箭头函数可以把作用域和this机制联系起来,但是却容易混淆,使代码难以维护。应该在作用域和this机制中二选一,否则它们就真的汇成一锅粥了。或者只使用词法作用域,或者只使用this机制,必要时使用bind()。尽量避免使用that=this和箭头函数
this机制系列介绍完了。最重要的还是第一篇this机制的绑定原则,第二篇this机制的优先级属于要点,而本篇则是拓展部分。如有不妥之处,欢迎交流
以上
深入理解this机制系列第三篇——箭头函数的更多相关文章
- 深入理解javascript作用域系列第三篇——声明提升(hoisting)
× 目录 [1]变量 [2]函数 [3]优先 前面的话 一般认为,javascript代码在执行时是由上到下一行一行执行的.但实际上这并不完全正确,主要是因为声明提升的存在.本文是深入理解javasc ...
- 深入理解javascript作用域系列第三篇
前面的话 一般认为,javascript代码在执行时是由上到下一行一行执行的.但实际上这并不完全正确,主要是因为声明提升的存在.本文是深入理解javascript作用域系列第三篇——声明提升(hois ...
- 深入理解DOM事件机制系列第三篇——事件对象
× 目录 [1]获取 [2]事件类型 [3]事件目标[4]事件代理[5]事件冒泡[6]事件流[7]默认行为 前面的话 在触发DOM上的某个事件时,会产生一个事件对象event,这个对象中包含着所有与事 ...
- 深入理解javascript对象系列第三篇——神秘的属性描述符
× 目录 [1]类型 [2]方法 [3]详述[4]状态 前面的话 对于操作系统中的文件,我们可以驾轻就熟将其设置为只读.隐藏.系统文件或普通文件.于对象来说,属性描述符提供类似的功能,用来描述对象的值 ...
- 深入理解javascript函数系列第三篇——属性和方法
× 目录 [1]属性 [2]方法 前面的话 函数是javascript中的特殊的对象,可以拥有属性和方法,就像普通的对象拥有属性和方法一样.甚至可以用Function()构造函数来创建新的函数对象.本 ...
- 深入理解javascript函数系列第三篇
前面的话 函数是javascript中特殊的对象,可以拥有属性和方法,就像普通的对象拥有属性和方法一样.甚至可以用Function()构造函数来创建新的函数对象.本文是深入理解javascript函数 ...
- javascript面向对象系列第三篇——实现继承的3种形式
× 目录 [1]原型继承 [2]伪类继承 [3]组合继承 前面的话 学习如何创建对象是理解面向对象编程的第一步,第二步是理解继承.本文是javascript面向对象系列第三篇——实现继承的3种形式 [ ...
- Webpack系列-第三篇流程杂记
系列文章 Webpack系列-第一篇基础杂记 Webpack系列-第二篇插件机制杂记 Webpack系列-第三篇流程杂记 前言 本文章个人理解, 只是为了理清webpack流程, 没有关注内部过多细节 ...
- 深入理解javascript作用域系列第四篇——块作用域
× 目录 [1]let [2]const [3]try 前面的话 尽管函数作用域是最常见的作用域单元,也是现行大多数javascript最普遍的设计方法,但其他类型的作用域单元也是存在的,并且通过使用 ...
随机推荐
- xpath使用
一.安装(win7 64) 1.安装lxml,pip install lxml 2.如果安装出错,下载lxml-3.5.0b1.win-amd64-py2.7.exe: 地址:http://www.l ...
- 体育游戏中的Player类
最近在做一个棒球的游戏,开始感觉还是挺酷炫的,但是其实做法挺朴实的,想象中的球员是多么智能,这样那样的,其实只是表象. 关于球员的类是游戏里非常重要的部分,这个玩意怎么写呢,可以这样写...... 棒 ...
- WPF-开机自启
#region 开机自启 /// <summary> /// 开机自启创建 /// </summary> /// <param name="exeName&qu ...
- Docker中images无法使用apt-get update解决方案
问题描述:使用apt-get update一直fail 原因:DNS设置错误 解决办法: nm-tool #查看DNS后面的数(IPv4),将后面的数copy下来 sudo nano /etc/def ...
- Linux上mongodb开机自启动
1.下载MongoDB 2.安装MongoDB(安装到/usr/local下) .tgz mongodb cd mongodb mkdir db mkdir logs cd bin vi mongod ...
- win32进程名查找进程PID
1. #include <Psapi.h> #pragma comment(lib, "Psapi.lib") DWORD GetProcIDFromName(LPCT ...
- jquery常见获取高度
jquery获取文档高度和窗口高度,$(document).height().$(window).height() $(document).height():整个网页的文档高度 $(window).h ...
- 用SQL语句将数据表中的数据保存为JSON格式
没有找到好的工具,只想到了拼字符串的方式,用 NVARCHAR(MAX) 可能有截断,不推荐使用,方法中使用了 FOR XML PATH('') 实现,有关其使用方法参考这里 表结构: SQL ...
- ubuntu14.04 安装 hadoop2.4.0
转载:ubuntu搭建hadoop-Ver2.6.0完全分布式环境笔记 自己在搭建hadoop平台时,碰到一些困难,按照该博文解决了问题,转载一下,作为记录. 2 先决条件 确保在你集群中的每个节点上 ...
- WebService的开发、部署、调用
本文参考其它文章和自己解决中间问题的经历记录,以C#开发WebService为例子,欢迎探讨: 一.C#开发WebService 在visual studio中新建ASP.NET Web服务应用程序, ...