前面的话

  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机制系列第三篇——箭头函数的更多相关文章

  1. 深入理解javascript作用域系列第三篇——声明提升(hoisting)

    × 目录 [1]变量 [2]函数 [3]优先 前面的话 一般认为,javascript代码在执行时是由上到下一行一行执行的.但实际上这并不完全正确,主要是因为声明提升的存在.本文是深入理解javasc ...

  2. 深入理解javascript作用域系列第三篇

    前面的话 一般认为,javascript代码在执行时是由上到下一行一行执行的.但实际上这并不完全正确,主要是因为声明提升的存在.本文是深入理解javascript作用域系列第三篇——声明提升(hois ...

  3. 深入理解DOM事件机制系列第三篇——事件对象

    × 目录 [1]获取 [2]事件类型 [3]事件目标[4]事件代理[5]事件冒泡[6]事件流[7]默认行为 前面的话 在触发DOM上的某个事件时,会产生一个事件对象event,这个对象中包含着所有与事 ...

  4. 深入理解javascript对象系列第三篇——神秘的属性描述符

    × 目录 [1]类型 [2]方法 [3]详述[4]状态 前面的话 对于操作系统中的文件,我们可以驾轻就熟将其设置为只读.隐藏.系统文件或普通文件.于对象来说,属性描述符提供类似的功能,用来描述对象的值 ...

  5. 深入理解javascript函数系列第三篇——属性和方法

    × 目录 [1]属性 [2]方法 前面的话 函数是javascript中的特殊的对象,可以拥有属性和方法,就像普通的对象拥有属性和方法一样.甚至可以用Function()构造函数来创建新的函数对象.本 ...

  6. 深入理解javascript函数系列第三篇

    前面的话 函数是javascript中特殊的对象,可以拥有属性和方法,就像普通的对象拥有属性和方法一样.甚至可以用Function()构造函数来创建新的函数对象.本文是深入理解javascript函数 ...

  7. javascript面向对象系列第三篇——实现继承的3种形式

    × 目录 [1]原型继承 [2]伪类继承 [3]组合继承 前面的话 学习如何创建对象是理解面向对象编程的第一步,第二步是理解继承.本文是javascript面向对象系列第三篇——实现继承的3种形式 [ ...

  8. Webpack系列-第三篇流程杂记

    系列文章 Webpack系列-第一篇基础杂记 Webpack系列-第二篇插件机制杂记 Webpack系列-第三篇流程杂记 前言 本文章个人理解, 只是为了理清webpack流程, 没有关注内部过多细节 ...

  9. 深入理解javascript作用域系列第四篇——块作用域

    × 目录 [1]let [2]const [3]try 前面的话 尽管函数作用域是最常见的作用域单元,也是现行大多数javascript最普遍的设计方法,但其他类型的作用域单元也是存在的,并且通过使用 ...

随机推荐

  1. WP8解析XML格式文件

    DOTA2 WebAPI请求返回的格式有两种,一种是XML,一种是JSON,默认是返回JSON格式,如果要返回XML格式的话,需要在加上format=xml. 这里举一个简单的解析XML格式的例子(更 ...

  2. asp.net中用cookie记住密码上次不用登陆

    ------最佳解决方案--------------------写入CookieResponse.Cookies["UserName"].Value = "用户名&quo ...

  3. AMD与CMD(转载)

    JavaSript模块化   在了解AMD,CMD规范前,还是需要先来简单地了解下什么是模块化,模块化开发?       模块化是指在解决某一个复杂问题或者一系列的杂糅问题时,依照一种分类的思维把问题 ...

  4. JS中原型链继承

    当我们通过构造函数A来实现一项功能的时候,而构造函数B中需要用到构造函数A中的属性或者方法,如果我们对B中的属性或者方法进行重写就会出现冗杂的代码,同时写出来也很是麻烦.而在js中每个函数都有个原型, ...

  5. JAVA实现AES 解密报错Input length must be multiple of 16 when decrypting with padded cipher

    加密代码 /**解密 * @param content 待解密内容 * @param password 解密密钥 * @return */ public static byte[] decrypt(b ...

  6. JavaScript 数组

    JavaScript 数组 简介:数组是值的有序集合,JavaScript在同一个数组中可以存放多种类型的元素,而且是长度也是可以动态调整的,可以随着数据增加或减少自动对数组长度做更改. 一:创建数组 ...

  7. 自定义 TableViewCell 的分割线

    刚开始自定义 tableViewCell 的时候,用的是直接在 cell 上加一张 imageView 的方法,如果在点击 cell 的时候有页面的跳转,这样做没什么问题,但是,如果在点击 cell ...

  8. txt文本变成html

    file_name = 'x.txt' f = open(file_name,'r') file_result = 'x.html' str_head = " LINE CI UTIL&qu ...

  9. 应用程序无法正常启动0xc0150002(windows server 2003)

    windows server 2003运行一个程序时出现 "应用程序无法正常启动0xc0150002"的错误提示; 解决方案: 下载地址:http://www.microsoft. ...

  10. 最近碰到的一些 SSL 问题记录

    最近碰到一些 SSL 的小问题,特记录下. 我们有个 Java 实现的 SSL TCP 服务端,为客户端(PC.Android 和 iOS)提供 SSL 接入连接服务.最近有用户反馈其手机上 App ...