深入理解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最普遍的设计方法,但其他类型的作用域单元也是存在的,并且通过使用 ...
随机推荐
- WP8解析JSON格式(使用Newtonsoft.Json包)
DOTA2 WebAPI请求返回的格式有两种,一种是XML,一种是JSON,默认是返回JSON格式. 这里举一个简单的解析JSON格式的例子(更多JSON操作): { "response&q ...
- 【BFS】POJ 3414
直达 -> POJ 3414 Pots 相似题联动–>HDU 1495 非常可乐 题意:两个壶倒水,三种操作,两个桶其中一个满足等于C的最少操作,输出路径.注意a,b互倒的时候能不能倒满, ...
- c和oc小知识
1.const const 修饰了*p1 / *p2 const int * p1=&age; int const * p2=&age;//和上面的意义一样 ,换句话说就是 在 “ * ...
- java的基础知识文件操作和标识符
1.文件夹的操作 dir :显示当前文件夹中的所有文件和文件夹. cd 路径: 进入到指定的路径. cd .. : 回到上一级目录 cd \ : 回到当前目录的跟目录 md 文件夹名 创建一个 ...
- Mysql远程访问
命令行: mysql -h 192.168.1.145 -u root -p 1.初始化root密码 进入mysql数据库 1mysql>update user set password=PAS ...
- HOJ 1797 Red and Black
传送门 http://acm.hit.edu.cn/hoj/problem/view?id=1797 总体的思路是遍历可以到达的' . ',将其对应的vis数组化为1,然后统计所有为1的vis项; ...
- java的poi技术读取和导入Excel
项目结构: http://www.cnblogs.com/hongten/gallery/image/111987.html 用到的Excel文件: http://www.cnblogs.com/h ...
- [转]Tesseract 3.02中文字库训练
下载chi_sim.traindata字库下载tesseract-ocr-setup-3.02.02.exe 下载地址:http://code.google.com/p/tesseract-ocr/d ...
- 【图文教程】Eclipse for PHP+XAMPP调试配置
一.下载安装XAMPP 下载地址:https://www.apachefriends.org/download.html, 一路“Next”,安装完毕. 二.下载Eclipse for PHP 下载地 ...
- PowerDesigner连接SQL Server
以前听说过PowerDesigner可以和数据库连接,根据在PowerDesigner创建的数据模型创建表.触发器.存储过程到数据库中.也可以将已有的数据库导出到PowerDesigner中为数据模型 ...