ES6 之箭头函数
wangjing013 opened this issue · comments
在 ES6
中引入新的创建函数的方式 箭头函数
它与普通函数有什么区别 ? 下面先来看看它的语法
及特性
.
箭头函数语法:
const getName = () => '张三';
const getAge = function(){ return 28 };
从语法层面看, 箭头函数与普通函数区别好像就是语法上的简写. 真的是这样 ? 显然不是.
下面了解箭头函数的特性,也就是它与普通函数的区别.
箭头函数特性:
1. 没有 this
指向的是全局上下文或外围最近一层非箭头函数的上下文.
2. 没有 arguments
通常函数内部都有一个 arguments
变量, 但箭头函数没有.
const arrowFunction = () => console.log(arguments);
arrowFunction(); //=> Uncaught ReferenceError: arguments is not defined
虽然自身没有, 但可以访问外围非箭头函数的 arguments
:
const createArrowFunction = function(name){
return () => arguments[0]
}
const arrowFunction = createArrowFunction('张三');
console.log(arrowFunction()); //=> 张三
之所以能够访问到, 因为作用域链
的存在.
3. 不能通过 new
去调用
const arrowFunction = () => 'arrowFunction';
new arrowFunction(); // Uncaught TypeError: arrowFunction is not a constructor
箭头函数内部不包含 [[Construct]]
方法, 当使用 new
关键调用会调用[[Construct]]
从而生成实例对象.
4. 没有 prototype
属性
const fn = function (){};
console.log(fn.prototype); //=> {constructor: ƒ}
const arrowFunction = () => 'arrowFunction';
console.log(arrowFunction.prototype); //=> undefined
由于不能使用 new
关键字调用箭头函数, 因而没有构建原型对象的需求. 所以箭头函数不存在 prototype
属性
5. 没有 super
连原型都没有,自然也不能通过 super
来访问原型的属性. 不过同 this
、arguments
一样它由其外层的非箭头函数决定.
class Parent {
show(msg) {
console.log(`Parent#show: ${msg}`);
}
}
class Child extends Parent {
method(arg) {
let inner = () => {
super.show(`arg = ${arg}`);
};
inner();
}
}
new Child().method('arg')
6. 没有 new.target
因为不能使用 new , 所以也就不存在 new.target
.
const arrowFunction = () => new.target; //=> Uncaught SyntaxError: new.target expression is not allowed here
具体new.target
可以参考这里
7. this
不可改变
通常JS允许我们通过 call
、apply
、bind
硬绑定的方式去更改 this
的值, 但是在箭头函数上无效.
const createArrowFunction = function(){
return () => { console.log(this) }
}
const arrowFunction = createArrowFunction();
arrowFunction.call({}); //=> window
const foo = function(){
console.log(this);
}
foo(); //=> window
foo.call({}); //=> {}
8. 不支持重复的函数命名参数(严格或非严格模式下)
const createArrowFunction = (name, name) => {}; //=> Uncaught SyntaxError: Duplicate parameter name not allowed in this context
箭头函数常见应用
- 事件绑定
const dom = {
bindEvent(){
const btn = document.querySelector("#btn");
btn.addEventListener('click', function(event){
this.show(); //=> Uncaught TypeError: this.show is not a function
})
},
show(){
console.log("show");
}
}
此时 this
表示当前点击当目标对象(event.target
), 它不存在 show
方法, 所以报错了.
在ES6之前, 通过闭包来解决这个问题, 修改如下:
const dom = {
bindEvent(){
const btn = document.querySelector("#btn");
const that = this;
btn.addEventListener('click', function(event){
that.show();
})
},
show(){
console.log("show"); //=> show
}
}
现在可以通过箭头函数来优雅解决该问题:
const dom = {
bindEvent(){
const btn = document.querySelector("#btn");
btn.addEventListener('click', (event) => {
that.show();
})
},
show(){
console.log("show"); //=> show
}
}
- 数组中的应用
通过数组map
函数修改对一个number
类型数组中的每一项进行累加, 如下:
const arr = [1,2,3,4,5,6];
// 通常写法如下
arr.map(function(val, index, arr){
return val + 1;
}) //=> [2, 3, 4, 5, 6, 7]
// 使用箭头函数
arr.map(val => val + 1); //=> [2, 3, 4, 5, 6, 7]
这里只是列举一些常见的用法. 其实还有很多用途.
总结
- 没有
this
、super
、arguments
和new.target
绑定,箭头函数中的this
、super
、arguments
和new.target
都是由外层的非箭头函数决定 - 不能通过
call
、apply
、bind
等方式修改this
的值 - 不能使用
new
关键字 - 没有
prototype
属性 - 没有
arguments
变量 - 在
JS
中常见错误来源, 在函数内很容易对 ``this ` 值失去控制, 其经常导致程序出现意想不到的行为. 箭头函数很好的消除这方面的烦恼.