ES6函数第三篇:函数篇(新增API与箭头函数)

1.新增API——new.target

众所周知,js中构造函数需使用new来调用,但是即使不使用new关键字,也可以调用构造函数,如【例1-1】,为了解决这一问题,js的解决方式为使用instanceof查看原型上是否有该构造函数,如【例1-2】,到了es6提供了一个特殊的API,可以使用该API在函数内部,判断该函数是否使用new来调用,如【例1-3】

【例1-1】构造函数的两种调用方式

function Person(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
    this.fullName = `${firstName}${lastName}`;
    //纯碎是为了让p1有返回值
    return `${this.firstName} ${this.lastName} ${this.fullName}`
}
const p1 = Person("J", "wh");
const p2 = new Person('T','hs');
console.log(p1);
console.log(p2);

【结果】 

图1-1

 【例1-2】之前的解决方式

function Person(firstName, lastName) {
    if (!(this instanceof Person)) {
        throw new Error('该函数没有使用new来调用')
    }
    this.firstName = firstName;
    this.lastName = lastName;
    this.fullName = `${firstName}${lastName}`;
}
const p2 = new Person('T','hs');
console.log(p2);
const p1 = Person("J", "wh");
console.log(p1);

【结果】

图1-2-1

细心的读者可能已经发现了,这种间接的方法可能导致人为改变this指向后,使得原型链上有构造函数,即该判断是可以避开的,存在bug,如下例

const p2 = new Person('T', 'hs');
console.log(p2);
const p3 = Person.call(p2, 'J', 'wh')
console.log(p3)

【结果】

图1-2-2

因此,es6提供了新的API —— new.target去直接解决这一问题,该表达式的用法是:当没有使用new调用函数时,返回undefined;若使用了new来调用,则得到new关键字后面的函数本身

【例1-3】

function Person(firstName, lastName) {
    if (new.target === undefined) {
        throw new Error('该函数没有使用new来调用')
    }
    this.firstName = firstName;
    this.lastName = lastName;
    this.fullName = `${firstName}${lastName}`;
}
const p2 = new Person('T', 'hs');
console.log(p2);
const p3 = Person.call(p2, 'J', 'wh')
console.log(p3);
图1-3

2.箭头函数

(1) this指向

  • 通过对象调用函数,this指向对象
  • 直接调用函数,this指向全局对象
  • 如果通过new调用函数,this指向新创建的对象
  • 如果apply,call,bind调用函数,this指向指定的数据
  • 如果是dom时间函数,this指向事件源

下面给个定时器的例子

【例2-1-1】

const obj = {
    count: 0,
    start: function () {
        setInterval(function () {
            this.count++;
            console.log(this.count);
        }, 1000)
    }
}
obj.start();

【结果】本来代码想实现的效果是, 没隔一秒count加1,但是由于定时器的this指向window,因此打印结果为

图2-1-1

之前的解决方式是,在start方法中保存this指向,如下,则可以解决该问题

const obj = {
    count: 0,
    start: function () {
        //保存this
        const self = this;
        setInterval(function () {
            self.count++;
            console.log(self.count);
        }, 1000)
    }
}
obj.start();

(2)箭头函数

es6在解决上述问题时引入了箭头函数。箭头函数是一个函数表达式,理论上,任何使用函数表达式的场景都可以使用箭头函数

语法规则

  • 完整语法:(参数1, 参数2,...) => {函数体}
  • 如果只有一个参数,可以省略小括号:参数=>{函数体}【例2-2-2】
  • 如果箭头函数只有一条返回语句,可以省略大括号,和return关键字:参数=>返回值

箭头函数的特点

  • 箭头函数中,不存在this,arguments,new.target,如果使用了,则是函数外层的对应的this,arguments,new.target
  • 箭头函数没有原型
  • 箭头函数不能作用构造函数使用

应用场景

  • 临时性使用的函数,并不会且不可以调用它,如:事件处理函数,异步处理函数,其他临时性的函数
  • 为了绑定外层this的函数
  • 在不影响其他代码的情况下,保持代码的简洁,最常见的,数组方法中的回调函数

【例2-2-1】

const obj = {
    count: 0,
    start: function () {
        setInterval(() =>{
            this.count++;
            console.log(this.count);
        }, 1000)
    }
}
obj.start();

【例2-2-2】

const print = num => {
    console.log('打印:', num);
}
print(2);

【例2-2-3】

const sum = (a,b)=> ({
    a:a,
    b:b,
    sum:a+b
});
console.log(sum(3,5));

【例2-2-4】

const numbers = [3, 7, 4, 8, 9];
const result = numbers.filter(num => num % 2 !== 0)
    .map(num => num * 2).reduce((a, b) => a + b)
console.log(result);

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值