资讯专栏INFORMATION COLUMN

ES6精解:箭头函数

HackerShell / 2279人阅读

摘要:基本用法在中允许使用来定义函数,如下就等同于从上面可以看出,在箭头左侧的是代表参数,若参数只有一个,可以省略,箭头右侧的表示函数代码块,若代码块里面是个返回值,则可以省略不写无参数情况若箭头函数不需要参数,则左侧用代替,如下无参数情况无参数

基本用法

在ES6中允许使用 => 来定义函数,如下:

 var f = a => a;
    console.log(f(1)); //1

就等同于

 var f = function(a){
         return a;
    }
    console.log(f(1)); //1

从上面可以看出,在箭头左侧的是代表参数,若参数只有一个,()可以省略,箭头右侧的表示函数代码块,若代码块里面是个返回值,则{}可以省略不写

1.无参数情况

若箭头函数不需要参数,则左侧用()代替,如下:

  var f = () => {
      console.log("无参数情况");
   }
    f();//无参数情况
2.有参数情况
  var f = (a, b) => {
        return a+b;
   }
    console.log(f(1,2)); //3
 var f = a => a;
 console.log(f(1)); //1

如果箭头函数有参数,则需要用()括起来,若只有一个参数,括号可以省略不写

在这里要注意一个情况,就是当箭头函数直接返回一个对象的时候,如下:

    var f = () => {name:"liming", age:22}; //报错
    console.log(f());

这样写肯定是报错的,因为{}执行时变成代码块,会去运行代码,所以要用一个()括起来才可以,如下:

var f = () => ({name:"liming", age:22}); 
console.log(f());

执行结果为:

{name: "liming", age: 22}

以上这个写法才是正确的

箭头函数注意点 1.this指向
 var a = "全局变量a";
    var obj={
        a:"局部变量a",
        fn1:function(){
            console.log(this.a);
        },
        fn2:()=>{
            console.log(this.a);
        }
    }
    obj.fn1();
    obj.fn2();

输出结果为:

局部变量a
全局变量a

普通函数的this我们知道是指向最近的一个对象,而箭头函数的this实际上是指向定义时的this,比如把上面代码改为:

 var obj={
        a:"局部变量a",
        fn1:function(){
            console.log(this.a);
        },
        fn2:()=>{
            console.log(this.a);
        }
    }
    obj.fn1();
    obj.fn2();

输出结果为:

局部变量a
undefined

此时因为箭头函数是指向全局的,全局没有变量a则输出undefined,这里的fn1和fn2都是全局函数,所以箭头函数this指向的是定义时的全局,而普通函数的this指向的是最近的一个对象

上面如果那个例子不太明白,可以再看下如下例子:

    this.a = "全局a";
    function Timer() {
         this.a = "timer中的a";
        // 普通函数
        setTimeout(function () {
            console.log("普通函数:", this.a);
        });

        // 箭头函数
        setTimeout(() => {
            console.log("箭头函数:",this.a);
    });
    }
   new Timer();

输出结果为:

普通函数: 全局a
箭头函数: timer中的a

这里普通函数会指向全局是因为,距离普通函数最近的对象是setTimeOut,而setTimeOut是挂在全局作用域中,所以普通函数指向全局,箭头函数指向的是定义时的对象,箭头函数是在Timer中定义的,所以箭头函数指向Timer

如果把以上代码改为如下:

 this.a = "全局a";
    function Timer() {
         this.a = "timer中的a";
        // 普通函数
        setTimeout(function () {
            console.log("普通函数:", this.a);
        });

        // 箭头函数
        setTimeout(() => {
            console.log("箭头函数:",this.a);
    });
    }
   Timer();

输出结果:

普通函数: timer中的a
箭头函数: timer中的a

这个是为什么呢,因为如果是new Timer相当于是构造函数,构造了一个对象,如果是Timer()就相当于是调用函数Timer()这两者还是有区别的,如果是调用函数Timer(),这个时候this的指向都是全局,在局部修改this.a会覆盖全局的this.a

通过以上,我们可以知道普通函数跟箭头函数this指向的区别是:

普通函数: this指向最靠近的一个对象

箭头函数: this指向定义时的对象,也就是说箭头函数一旦定义完成,它的指向是固定的,没法改变,它的指向是定义时所在的作用域,而不是执行时的作用域

2.不可以当做构造函数

箭头函数不可以当做构造函数,也就是不可以new一个,否则会报错,如下:

    var fn = ()=>{
        console.log("123");
    }
    new fn(); //Uncaught TypeError: fn is not a constructor

以上会报错,因为箭头函数本身没有属于自己的this,所以箭头函数不可以当做构造函数,也因为箭头函数没有自己的this,所以call()、apply()、bind()这些方法去改变this的指向对箭头函数也是无效的,如下:

  this.x = "outer";
    (function() {
        console.log([
            (() => this.x).bind({ x: "inner" })()
        ]);
    })();

输出结果为:

["outer"]

把箭头函数通过bind绑定可见无效,箭头函数还是指向全局

以上是个人总结,有什么不足之处欢迎留言探讨!

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/95719.html

相关文章

  • ES6精解:promise用法

    前言 今天就简单总结一下promise的用法,在用promise之前,我们要先了解一下什么promise,这个东西是用来干什么的? 通俗易懂的讲,promise其实就是一个构造函数,是用来解决异步操作的,我们平时其实还是会用到挺多的,比如我们经常会嵌套一层层的函数 step1(function (value1) { step2(value1, function(value2){ s...

    enali 评论0 收藏0
  • ES6精解:变量的解构赋值

    摘要:真正被赋值的是后者,而不是前者。第一行语句中,模式是取数组的第一个成员,跟圆括号无关第二行语句中,模式是,而不是第三行语句与第一行语句的性质一致。本文参考链接主要是看了阮一峰老师的文章,自己整理了一下,供后期自己看笔记用的 1.数组的解构赋值 我们知道以前我们给一个变量赋值要这样如下: let a = 1; let b = 2; let c = 3; 但是ES6出来之后,我们可以这样:...

    neu 评论0 收藏0
  • ES6精解:let、const、块级作用域

    摘要:命令新增了命令,跟类似,都是用来声明变量的不允许重复声明报错不存在变量提升报错正确写法为既要先定义,后面才能有这个值,否则会报错,如果改成会提示未定义,但是就直接报错了暂时性死区只要在块级作用域里面存在则它所声明的变量就绑定在这个块级作用域 let命令 ES6新增了let命令,跟var类似,都是用来声明变量的 1.不允许重复声明 { let a = 1; let a =...

    BWrong 评论0 收藏0
  • JavaScript 编程精解 中文第三版 三、函数

    摘要:当控制流遇到这样的语句时,它立即跳出当前函数并将返回的值赋给调用该函数的代码。函数声明不是常规的从上到下的控制流的一部分。该函数调用控制台的来完成它的工作,然后将控制流返回到第行。 来源:ApacheCN『JavaScript 编程精解 中文第三版』翻译项目原文:Functions 译者:飞龙 协议:CC BY-NC-SA 4.0 自豪地采用谷歌翻译 部分参考了《JavaScript ...

    xuexiangjys 评论0 收藏0
  • JavaScript 编程精解 中文第三版 十五、处理事件

    摘要:事件与节点每个浏览器事件处理器被注册在上下文中。事件对象虽然目前为止我们忽略了它,事件处理器函数作为对象传递事件对象。若事件处理器不希望执行默认行为通常是因为已经处理了该事件,会调用事件对象的方法。 来源:ApacheCN『JavaScript 编程精解 中文第三版』翻译项目原文:Handling Events 译者:飞龙 协议:CC BY-NC-SA 4.0 自豪地采用谷歌翻译 部分...

    Clect 评论0 收藏0

发表评论

0条评论

HackerShell

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<