美文网首页
箭头函数

箭头函数

作者: Mancaulist | 来源:发表于2019-01-19 11:08 被阅读0次

廖雪峰-箭头函数

箭头函数

基础语法:

(参数1, 参数2, …, 参数N) => { 函数声明 }

//相当于:(参数1, 参数2, …, 参数N) =>{ return 表达式; }
(参数1, 参数2, …, 参数N) => 表达式(单一)

// 当只有一个参数时,圆括号是可选的:
(单一参数) => {函数声明}
单一参数 => {函数声明}

// 没有参数的函数应该写成一对圆括号。
() => {函数声明}

高级语法:

//加括号的函数体返回对象字面表达式:
参数=> ({foo: bar})

//支持剩余参数和默认参数
(参数1, 参数2, ...rest) => {函数声明}
(参数1 = 默认值1,参数2, …, 参数N = 默认值N) => {函数声明}

//同样支持参数列表解构
let f = ([a, b] = [1, 2], {x: c} = {x: a + b}) => a + b + c;
f();  // 6

ES6标准新增了一种新的函数:Arrow Function(箭头函数)。

为什么叫Arrow Function?因为它的定义用的就是一个箭头:

x => x * x

上边的箭头函数相当于

function (x) {
    return x * x;
}

箭头函数相当于匿名函数,并且简化了函数定义。箭头函数有两种格式,一种像上面的,只包含一个表达式,连{ ... }return都省略掉了。还有一种可以包含多条语句,这时候就不能省略{ ... }return

x => {
    if (x > 0) {
        return x * x;
    }
    else {
        return - x * x;
    }
}

如果参数不是一个,就需要用括号()括起来:

// 两个参数:
(x, y) => x * x + y * y

// 无参数:
() => 3.14

// 可变参数:
(x, y, ...rest) => {
    var i, sum = x + y;
    for (i=0; i<rest.length; i++) {
        sum += rest[i];
    }
    return sum;
}

如果要返回一个对象,就要注意,如果是单表达式,这么写的话会报错:

// SyntaxError:
x => { foo: x }

因为和函数体的{ ... }有语法冲突,所以要改为:

// ok:
x => ({ foo: x })

箭头函数注意点

  1. typeof运算符和普通的function一样
var func = a => a
console.log(typeof func); // "function"
  1. instanceof也返回true,表明也是Function的实例
console.log(func instanceof Function); // true
  1. this固定,不再善变
obj = {
    data: ['John Backus', 'John Hopcroft'],
    init: function() {
        document.onclick = ev => {
            alert(this.data) // ['John Backus', 'John Hopcroft']
        }
        // 非箭头函数
        // document.onclick = function(ev) {
        //     alert(this.data) // undefined
        // }
    }
}
obj.init()
  1. 箭头函数不能用new
var Person = (name, age) => {
    this.name = name
    this.age = age
}
var p = new Person('John', 33) // error
  1. 不能使用argument
var func = () => {
    console.log(arguments)
}
func(55) // Uncaught ReferenceError: arguments is not defined

箭头函数this

箭头函数看上去是匿名函数的一种简写,但实际上,箭头函数和匿名函数有个明显的区别:箭头函数内部的this是词法作用域,由上下文确定。

// 该模块为jc个人理解
var obj= {
    name:'obj',
    li:function() {
        // 这里的上下文是obj.li,所以this指代的就是obj.li的this,所以指向obj
        console.log(this);  // obj
    },
    fe: () => {
        // 这里的上下文是obj,所以this指代的就是obj的this,所以指向window
        console.log(this);  // window
    }
}

可以参考:箭头函数-MDN

由于JavaScript函数对this绑定的错误处理,下面的例子无法得到预期结果:

var obj = {
    birth: 1990,
    getAge: function () {
        var b = this.birth; // 1990
        var fn = function () {
            return new Date().getFullYear() - this.birth; // this指向window或undefined
        };
        return fn();
    }
};

现在,箭头函数完全修复了this的指向,this总是指向词法作用域,也就是外层调用者obj

var obj = {
    birth: 1990,
    getAge: function () {
        var b = this.birth; // 1990
        var fn = () => new Date().getFullYear() - this.birth; // this指向obj对象
        return fn();
    }
};
obj.getAge(); // 25

如果使用箭头函数,以前的那种hack写法:

var that = this;

就不再需要了。

由于this在箭头函数中已经按照词法作用域绑定了,所以,用call()或者apply()调用箭头函数时,无法对this进行绑定,即传入的第一个参数被忽略:

var obj = {
    birth: 1990,
    getAge: function (year) {
        var b = this.birth; // 1990
        var fn = (y) => y - this.birth; // this.birth仍是1990
        return fn.call({birth:2000}, year);
    }
};
obj.getAge(2015); // 25

我们再看个例子

<p id="test1">测试</p>

var p1 = document.getElementById('test1');
p1.addEventListener('click', () => {
    p1.style.color = "red";
}, false);

在es5中相当于

 var p1 = document.getElementById('test1');
 p1.addEventListener('click', function () {
     //直接通过dom的方法改变颜色
     this.style.color = "red";
 },false);

我们思考一个问题——当我们把第一段代码中的p1换成this时this会指向哪里

p1.addEventListener('click', () => {
    this.style.color = "red";//   'color' is not undefined
}, false);

箭头函数内的this对象,就是定义时所在的对象,而不是使用时所在的对象。
this对象的指向是可变的,但是在箭头函数中,它是固定的。

function foo() {
  setTimeout(() => {
    console.log('id:', this.id);
  }, 100);
}

var id = 21;

foo.call({ id: 42 });
// id: 42

上面代码中,setTimeout的参数是一个箭头函数,这个箭头函数的定义生效是在foo函数生成时,而它的真正执行要等到100毫秒后。如果是普通函数,执行时this应该指向全局对象window,这时应该输出21。但是,箭头函数导致this总是指向函数定义生效时所在的对象(本例是{id: 42}),所以输出的是42

相关文章:
关于ES6中箭头函数的this问题
JavaScript 中this与Dom

总结:

箭头函数内的this对象,就是定义时所在的对象,而不是使用时所在的对象。
this对象的指向是可变的,但是在箭头函数中,它是固定的。

相关文章

  • ES6~箭头函数

    什么是箭头函数 单表达式箭头函数 相当于 多表达式箭头函数 箭头函数相当于匿名函数,并且简化了函数定义。箭头函数有...

  • 箭头函数和立即执行函数

    箭头函数 箭头函数和普通函数有什么区别?如果把箭头函数转换为不用箭头函数的形式,如何转换主要是this的差别,箭头...

  • 学习 ES 6 箭头函数

    箭头函数的用法 ES6 允许使用“箭头”(=>)定义函数。 箭头函数的一个用处是简化回调函数。 箭头函数 this...

  • 箭头函数

    箭头函数 箭头函数能让this的指向固定化 分析:1)第一个setInterval()中使用了箭头函数,箭头函数使...

  • TS  笔记this

    this 箭头函数在箭头函数创建的地方获得this;非箭头函数,在调用函数的地方获得this如图

  • 箭头函数和数组

    箭头函数&数组 箭头函数 特点: 没有 this 没有 arguments 没有prototype在箭头函数中使用...

  • 箭头函数

    箭头函数 为什么使用箭头函数

  • 箭头函数中this的指向

    箭头函数在平时开发中用着非常爽,箭头函数有什么特点呢 箭头函数不能够当做构造函数使用 箭头函数没有argument...

  • js学习笔记4(函数)

    1.箭头函数 ES6新增属性。箭头函数特别适合嵌入函数的场景。 箭头函数虽然语法简介,但是很多场合不适用。箭头函数...

  • js理解普通函数和箭头函数

    普通函数: 箭头函数: 区别: 构造函数和原型 箭头函数不能作为构造函数 不能new。会报错 箭头函数没有原型属性...

网友评论

      本文标题:箭头函数

      本文链接:https://www.haomeiwen.com/subject/xfgodqtx.html