箭头函数与一般函数有啥区别?
ES6 遍及后,箭头函数越来越多的呈现在咱们的日常开发中,那么箭头函数与一般函数到底由什么区别呢?
波及相干知识点
- new 操作符
- new.target
- prototype
- 浏览器事件
- Object.prototype.defineProperty
- call、bind、apply
- prototype
- arguments 对象
无 this
绑定
箭头函数没有本人的this
,它会从本人的作用域链的父级继承this
。
为了更好的了解下面的这段话,咱们来举几个例子
如何了解无 this
绑定?
例子 1:页面的事件回调函数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title> 事件回调中函数的 this</title>
</head>
<body>
<button id="arrow-function"> 箭头函数 </button>
<button id="regular-function"> 一般函数 </button>
</body>
<script>
const arrowFunctionButton = document.querySelector("#arrow-function");
const regularFunctionButton = document.querySelector("#regular-function");
arrowFunctionButton.addEventListener("click", () => {console.log(this); // this 指向 window ①
});
regularFunctionButton.addEventListener("click", function () {console.log(this); // this 指向以后的点击元素 ②
});
function Wrapper() {let arrowFunction = () => {console.log('我是被包裹箭头函数的 this >>>', this);
}
document.addEventListener('click', arrowFunction);
}
let object = new Wrapper(); // ③
</script>
</html>
让咱们再来回顾一遍箭头函数中 this 的个性
箭头函数没有本人的 this,它会从本人的作用域链的父级继承 this。
因而在①中,这个回调函数作用域链的父级是window
,因而打印进去的后果是window
事件回调的函数如果是一般函数,此时 this
将会指向以后被点击的元素,因而②中打印出的后果是<button id="regular-function"> 一般函数 </button>
执行后果如下:
请留神,箭头函数会依据应用地位而不是定义地位继承词法作用域。当应用 new
运算符时,像执行对象的构造函数那样来执行函数。因而函数外部的每条语句都将在实例化对象 object
的语境中执行,而不是在 window
的语境中执行。因而在③中,咱们能够晓得,this
指向实例化的object
。
执行后果如下:
例子 2:Object.prototype.defineProperty
办法
上面是一个来自 MDN
的例子,解释了为何咱们很少看见在 definePrototype
中应用箭头函数
var obj = {a: 10};
Object.defineProperty(obj, "b", {get: () => {console.log(this.a, typeof this.a, this); // this 指向 window
return this.a+10;
}
});
obj.b; // NaN
执行后果如下:
因为箭头函数的 this
指向 window
,而window
内并未定义 a
属性,因而:this
等价于 window
,this.a
等价于 undefined
,而this.a + 10
实际上等价于 undefined + 10
后果为NaN
call
、apply
、bind
调用将会疏忽第一个参数
window.a = 1;
const obj = {a: 2};
const uselessCall = (arg) => {console.log('我是 this >>>', this, '我是 this.a >>>', this.a, '我是传入值 >>>', arg);
}
function usefulCall (arg) {console.log('我是 this >>>', this, '我是 this.a >>>', this.a, '我是传入值 >>>', arg);
}
uselessCall.call(obj, 10);
usefulCall.call(obj, 10);
执行后果如下:
因为箭头函数没有本人的 this
,将会导致通过call
、apply
、bind
调用一个箭头函数时,疏忽第一个参数。当没有指定第一个参数时,将会默认绑定window
。前面传入的参数仍旧无效。
无 arguments
对象
箭头不绑定 arguments
对象,一般函数绑定 arguments
对象。
如果你在箭头函数中想要拜访 arguments
对象,将会产生援用谬误:
const noArguments = () => console.log(arguments);
noArguments();
执行后果如下:
在一般函数中,咱们能够应用 arguments
对象
function hasArguments() {console.log(arguments);
}
hasArguments();
执行后果如下:
小提示
如果你心愿在箭头函数中获取函数传入参数,请间接应用残余参数
来获取const restParameters = (...args) => console.log(args);
无构造函数
应用 new
操作符报错
箭头函数不能用于结构,因而应用 new
将会报错
const ErrorNew = () => {};
new ErrorNew;
执行后果如下:
无new.target
因为无奈被 new
运算符调用,因而箭头函数同样不领有new.target
。
const noNewTarget = () => console.log(new.target);
执行后果如下:
无 prototype
属性
箭头函数没有 prototype
属性,如果试图设置 prototype
属性,将会报错!
const NoPrototype = () => {};
console.log(NoPrototype.prototype); // undefined
NoPrototype.prototype.age = 11; // 抛出谬误
执行后果如下: