-
箭头函数没有 prototype,所以箭头函数本身没有 this
this存在的其中一个目的是可以改变函数的上下文,改变了上下文就改变了函数的原型prototype,那箭头函数没有this也就没有prototype ```js // 箭头函数 let a = () => {}; console.log(a.prototype); // undefined // 普通函数 function a() {}; console.log(a.prototype); // {constructor:f} ```
-
箭头函数不会创建自己的 this
箭头函数没有自己的 this,箭头函数的 this 指向在定义的时候继承自外层第一个普通函数的 this。
var id = "Global"; function fun1() { // setTimeout中使用普通函数 setTimeout(function () { console.log(this.id); }, 2000); } function fun2() { // setTimeout中使用箭头函数 setTimeout(() => { console.log(this.id); }, 2000); } fun1.call({ id: "Obj" }); // 'Global' fun2.call({ id: "Obj" }); // 'Obj'
函数 fun1 中的 setTimeout 中使用普通函数,2 秒后函数执行时,这时函数其实是在全局作用域执行的,所以 this 指向 Window 对象,this.id 就指向全局变量 id,所以输出’Global’。 但是函数 fun2 中的 setTimeout 中使用的是箭头函数,这个箭头函数的 this 在定义时就确定了,它继承了它外层 fun2 的执行环境中的 this,而 fun2 调用时 this 被 call 方法改变到了对象{id: ‘Obj’}中,所以输出’Obj’。
var id = "GLOBAL"; var obj = { id: "OBJ", a: function () { console.log(this.id); }, b: () => { console.log(this.id); }, }; obj.a(); // 'OBJ' obj.b(); // 'GLOBAL'
对象 obj 的方法 a 使用普通函数定义的,普通函数作为对象的方法调用时,this 指向它所属的对象。 所以,this.id 就是 obj.id,所以输出’OBJ’。 但是方法 b 是使用箭头函数定义的,箭头函数中的 this 实际是继承的它定义时所处的全局执行环境中的 this,所以指向 Window 对象,所以输出’GLOBAL’。(这里要注意,定义对象的大括号{}是无法形成一个单独的执行环境的,它依旧是处于全局执行环境中!!)
-
call | apply | bind 无法改变箭头函数中 this 的指向
call | apply | bind 方法可以用来动态修改函数执行时 this 的指向,但由于箭头函数的 this 定义时就已经确定且永远不会改变。所以使用这些方法永远也改变不了箭头函数 this 的指向。
var id = "Global"; // 箭头函数定义在全局作用域 let fun1 = () => { console.log(this.id); }; fun1(); // 'Global' // this的指向不会改变,永远指向Window对象 fun1.call({ id: "Obj" }); // 'Global' fun1.apply({ id: "Obj" }); // 'Global' fun1.bind({ id: "Obj" })(); // 'Global'
-
箭头函数不能作为构造函数使用
我们先了解一下构造函数的new都做了些什么?简单来说,分为四步: - JS内部首先会先生成一个对象; - 再把函数中的this指向该对象; - 然后执行构造函数中的语句; - 最终返回该对象实例。 <br> 但是!!因为箭头函数没有自己的this,它的this其实是继承了外层执行环境中的this,且this指向永远不会随在哪里调用、被谁调用而改变,所以箭头函数不能作为构造函数使用,或者说构造函数不能定义成箭头函数,否则用new调用时会报错! ```js let Fun = (name, age) => { this.name = name; this.age = age; }; // 报错 let p = new Fun('cao', 24); ```
-
箭头函数没有自己的 arguments
箭头函数没有自己的 arguments 对象。在箭头函数中访问 arguments 实际上获得的是外层局部(函数)执行环境中的值。
// 例子一 let fun = val => { console.log(val); // 111 // 下面一行会报错 // Uncaught ReferenceError: arguments is not defined // 因为外层全局环境没有arguments对象 console.log(arguments); }; fun(111); // 例子二 function outer(val1, val2) { let argOut = arguments; console.log(argOut); // ① let fun = () => { let argIn = arguments; console.log(argIn); // ② console.log(argOut === argIn); // ③ }; fun(); } outer(111, 222);
普通函数 outer 内部的箭头函数 fun 中的 arguments 对象,其实是沿作用域链向上访问的外层 outer 函数的 arguments 对象。 可以在箭头函数中使用 rest 参数代替 arguments 对象,来访问箭头函数的参数列表!!
- 箭头函数不能用作 Generator 函数,不能使用 yeild 关键字