美文网首页
箭头函数的几个使用注意点

箭头函数的几个使用注意点

作者: 肥羊猪 | 来源:发表于2021-03-04 09:07 被阅读0次

箭头函数:

更简洁的语法
没有this
不能使用new 构造函数
不绑定arguments,用rest参数...解决
使用call()和apply()调用
捕获其所在上下文的 this 值,作为自己的 this 值
箭头函数没有原型属性
不能简单返回对象字面量
箭头函数不能当做Generator函数,不能使用yield关键字
箭头函数不能换行
箭头函数的 this 永远指向其上下文的 this ,任何方法都改变不了其指向,如 call() , bind() , apply()
普通函数的this指向调用它的那个对象

1.函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象

普通的函数里面的this是指向运行时的作用域.
箭头函数中的this是绑定定义时所在的作用域的。
可以使用箭头函数使this指向固定化,这种特性很有利于封装回调函数

普通函数
function foo() {
  setTimeout(function() {
    console.log('id:', this.id);
    //setTimeout里面的回调函数运行的时候的作用域是window,但是this定义的时候的作用域是函数foo。
  }, 100);
}
var id = 21;
foo.call({ id: 42 });            //id: 21

箭头函数
function foo() {
  setTimeout(() => {
    console.log('id:', this.id);
//箭头函数导致this总是指向函数定义生效时所在的对象
  }, 100);
}
var id = 21;
foo.call({ id: 42 });            //id: 42

实际箭头函数根本没有自己的this,导致内部的this就是外层代码块的this

// ES6
function foo() {
  setTimeout(() => {
    console.log('id:', this.id);        //其实这里的this就是使用了外层作用域的this
  }, 100);
}

// ES5
function foo() {
  var _this = this;            //将外层作用域的this复制给一个变量
  setTimeout(function () {
    console.log('id:', _this.id);
  }, 100);
}

2.不可以当作构造函数,也就是说,不能使用new命令,否则会抛出一个错误

箭头函数没有自己的this,所以理所当然箭头函数不可以当作构造函数

var fun = (id, name) => {
    this.id = id;
    this.name = name;
    this.showName = () => {
        console.log(this.name);
    }
};
let obj = new fun(1, "hdl");     //TypeError: fun is not a constructor
//说fun不是一个构造函数,这也反过来印证了第一点,箭头函数没有this。
obj.showName();

3.不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用rest参数代替。

function func1(a, b) {
    console.log(arguments);
    //Arguments(2) [1, 2, callee: ƒ, Symbol(Symbol.iterator): ƒ]
}

let func2 = (a, b) => {
    console.log(arguments);     //arguments is not defined
}
改成
let func2 = (...rest) => {
    console.log(rest);     //[1, 2]
}

func1(1, 2);
func2(1, 2);

4.没有new.target

new.targetES6新引入的属性,普通函数如果通过new调用,new.target会返回该函数的引用

function Cat() {
    console.log(new.target); 
}
let cat = new Cat(); // ƒ Cat() { console.log(new.target); }
用于确定构造函数是否为new调用的。

箭头函数里使用new.target报错

// 普通函数
let a = function() {
    console.log(new.target);
}
a(); // undefined

// 箭头函数
let b = () => {
    console.log(new.target); // 报错:Uncaught SyntaxError: new.target expression is not allowed here
};
b();

5.没有原型super

由于不能通过new关键字调用,不能作为构造函数,所以箭头函数不存在 prototype这个属性

let func = () => {};
console.log(func.prototype) // undefined

箭头函数没有原型,也不能通过 super来访问原型的属性,所以箭头函数也是没有 super的。同this、arguments、new.target一样,这些值由外围最近一层非箭头函数决定。

6.call/apply/bind方法无法改变箭头函数this的指向

call()、apply()、bind()方法的共同特点是可以改变this的指向,用来动态修改函数执行时this的指向。箭头函数的this定义时就已经确定了且不会改变

var name = 'global name';
var obj = {
    name: 'huangdonglu'
}
// 箭头函数定义在全局作用域
let func = () => {
    console.log(this.name);
};

func();     // global name
// this的指向不会改变,永远指向Window对象,放到到window下的全局变量
func.call(obj);     // global name
func.apply(obj);    // global name
func.bind(obj)();   // global name

7.箭头函数的解析顺序相对靠前

虽然箭头函数中的箭头不是运算符,但箭头函数具有与常规函数不同的特殊运算符优先级解析规则

let a = false || function() {}; // ok
let b = false || () => {}; // SyntaxError: Malformed arrow function parameter list
let c = false || (() => {}); // ok

8.箭头函数不支持重名参数

function foo(a, a) {
    console.log(a, arguments); // 2 Arguments(2) [1, 2, callee: ƒ, Symbol(Symbol.iterator): ƒ]
}

var boo = (a, a) => { // 直接报错:Uncaught SyntaxError: Duplicate parameter name not allowed in this context
    console.log(a);
};
foo(1, 2);
boo(1, 2);

9.不可以使用yield命令,因此箭头函数不能用作 Generator函数。

箭头函数不适用的场景

1.第一个场合是定义对象的方法,且该方法内部包括this
如下:对象不构成单独的作用域,导致jumps箭头函数定义时的作用域就是全局作用域

对象里面的函数使用箭头函数
const cat = {
    lives: 9,
    jumps : () => {
        this.lives--;
    }
};
cat.jumps();
console.log(cat.lives);     //9

对象里面的方法使用普通方法
const cat = {
    lives: 9,
    jumps() {
        this.lives--;
    }
};
cat.jumps();
console.log(cat.lives);     //8

2.需要动态this时,也不应该使用箭头函数。

var btn = document.getElementById('btn');
btn.addEventListener('click', () => {
  console.log(this);//this就是全局对象 不是btn
如果改成普通函数,this就会动态指向被点击的按钮对象。
});

3.具有动态上下文回调函数,也不应使用箭头函数
4.不能应用在构造函数
5.避免在 prototype上使用
6.避免在需要 arguments上使用

相关文章

  • ECMAScript 6 箭头函数

    箭头函数 ES6 允许使用“箭头”(=>)定义函数。 使用注意点 箭头函数有几个使用注意点。 (1)函数体内的th...

  • ES6入门=>箭头函数

    ES6允许使用“箭头”(=>)定义函数。 使用注意点箭头函数有几个使用注意点。 (1)函数体内的this对象,就是...

  • 2019-02-21

    函数的扩展 2、箭头函数 使用注意点 箭头函数有几个注意点:1、函数体内的this对象,就是定义时所在的对象,而不...

  • es6--箭头函数的注意点

    箭头函数有几个使用注意点。 (1)函数体内的this对象,是定义箭头函数时所在的执行环境中的this对象,切记 (...

  • es6之箭头函数

    使用注意点 箭头函数有几个使用注意点。(1)函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。...

  • es6中箭头函数this指向(3)

    ES6 箭头函数this指向 箭头函数有几个使用注意点。 (1)函数体内的this对象,就是定义时所在的对象,而不...

  • 箭头函数的几个使用注意点

    箭头函数: 1.函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象 普通的函数里面的this是指...

  • Es6 箭头函数

    转换 箭头函数有几个使用注意点。 (1)函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。 (...

  • 箭头函数不能使用的场景

    使用箭头函数注意点: 箭头函数内的this对象就是定义时所在的对象,不是使用时所在的对象 箭头函数不可以当作构造函...

  • ES6 ---- 函数

    函数参数的默认值 与解构赋值配合使用 rest参数 箭头函数 使用箭头函数的注意点 函数体内的this对象,是定义...

网友评论

      本文标题:箭头函数的几个使用注意点

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