我问这个问题是因为我和我的同事在编码风格上有争议,因为他更喜欢箭头函数声明:
const sum = (a, b) => a + b;
我更喜欢旧式的独立函数声明:
function sum(a, b) {
return a + b;
}
我的观点是旧式代码更具可读性,您可以更清楚地区分函数和变量声明。他的观点是带有箭头函数的代码运行得更快。
当您使用旧式独立函数声明而不是箭头函数时,您是否了解实际性能损失(在 v8 中)?这种惩罚真的存在吗?
我问这个问题是因为我和我的同事在编码风格上有争议,因为他更喜欢箭头函数声明:
const sum = (a, b) => a + b;
我更喜欢旧式的独立函数声明:
function sum(a, b) {
return a + b;
}
我的观点是旧式代码更具可读性,您可以更清楚地区分函数和变量声明。他的观点是带有箭头函数的代码运行得更快。
当您使用旧式独立函数声明而不是箭头函数时,您是否了解实际性能损失(在 v8 中)?这种惩罚真的存在吗?
V8 开发人员在这里。箭头函数(大部分)只是传统函数声明的“语法糖”。没有性能差异。
以下表明:
function goFat() {
for (var i = 0; i < 1000000; i++) {
var v = ()=>{};
v();
}
}
function goTraditional() {
for (var i = 0; i < 1000000; i++) {
var v = function() {};
v();
}
}
function race() {
var start = performance.now();
goTraditional();
console.log('Traditional elapsed: ' + (performance.now() - start));
start = performance.now();
goFat()
console.log('Fat elapsed: ' + (performance.now() - start));
start = performance.now();
goTraditional();
console.log('Traditional elapsed: ' + (performance.now() - start));
start = performance.now();
goFat()
console.log('Fat elapsed: ' + (performance.now() - start));
console.log('------');
}
<button onclick="race()">RACE!</button>
我认为类属性中的箭头函数可能会导致一些性能问题。这是一个例子:
class Car {
setColor = (color) => { this.color = color; }
constructor() {
this.color = '';
this.getColor = () => { return this.color; };
}
printCarColor() {
console.log(this.color);
}
}
var c = new Car();
console.log(c);
如果我们查看变量 c,您会注意到函数setColor和getColor是为每个实例创建的全新副本,并且每个新副本都放置在每个实例上,而函数 printCarColor 驻留在原型上。
如果你想让一千个实例每个都能够进行固定上下文的方法引用,你将需要一千个单独的方法(不是一个共享的),当然然后你将不得不存储这千个中的每一个实例本身上的单独方法,从而破坏了单个共享原型的全部意义。
nodejs有两个例子:
function testFat(a, b) {
return a + b;
}
let testArrow = (a, b) => a + b;
let t1 = process.hrtime();
let tmp1 = 0;
for (let i = 0; i < 1000000000; ++i) {
tmp1 = testFat(tmp1, i);
}
var fatTime = process.hrtime(t1);
console.log('fat', fatTime);
let t2 = process.hrtime();
let tmp2 = 0;
for (let i = 0; i < 1000000000; ++i) {
tmp2 = testArrow(tmp2, i);
}
var arrowTime = process.hrtime(t2);
console.log('arrow', arrowTime);
function testFat() {
return 0;
}
let testArrow = () => 0;
let t1 = process.hrtime();
for (let i = 0; i < 1000000000; ++i) {
testFat();
}
var fatTime = process.hrtime(t1);
console.log('fat', fatTime);
let t2 = process.hrtime();
for (let i = 0; i < 1000000000; ++i) {
testArrow();
}
var arrowTime = process.hrtime(t2);
console.log('arrow', arrowTime);```
结果是:
bash-3.2$ 节点 test_plus_i.js
脂肪 [ 0, 931986419 ]
箭头 [ 0, 960479009 ]
bash-3.2$ 节点 test_zero.js
脂肪 [ 0, 479557888 ]
箭头 [ 0, 478563661 ]
bash-3.2$ 节点 --version
v12.8.0
bash-3.2$
所以你可以看到函数调用开销没有区别。
在我的 exp 中,我发现箭头函数确实比普通的 JS 函数运行得更快。这是 react 中的一个小片段,它使用了箭头和普通函数。我发现使用箭头函数的组件比使用普通 js 函数的组件运行速度要快一些。
https://codepen.io/lokeshpathrabe/pen/qgzadx
class Fun extends React.Component {
constructor(props){
super(props);
this.state = {start: new Date().getTime(),
end: new Date().getTime(),
number: 0};
console.log('Function start: ', this.state.start);
const fun = function(me){
let n = me.state.number
me.setState({
...me.state, end: new Date().getTime(), number: ++n
})
}
this.interval = setInterval(fun, 1, this);
}
stop(){
clearInterval(this.interval);
}
componentDidUpdate(){
if((this.state.end - this.state.start) > 5000){
console.log('Function end: ', this.state.end);
clearInterval(this.interval)
}
}
render() {
return (
<div>
<h2>Counter with Function {this.state.number}</h2>
</div>
)
}
}
class Arrow extends React.Component {
constructor(props){
super(props);
this.state = {start: new Date().getTime(),
end: new Date().getTime(),
number: 0};
console.log('Arrow start: ', this.state.start);
this.interval = setInterval(()=>{
let n = this.state.number
this.setState({
...this.state, end: new Date().getTime(), number: ++n
})
}, 1);
}
stop(){
clearInterval(this.interval);
}
componentDidUpdate(){
if((this.state.end - this.state.start) > 5000){
console.log('Arrow end: ', this.state.end);
clearInterval(this.interval)
}
}
render() {
return (
<div>
<h2>Counter with Arrow {this.state.number}</h2>
</div>
)
}
}
class HOC extends React.Component {
render() {
return (<div>
<h1>The one reaching higher count wins</h1>
<Arrow/>
<Fun/>
</div>);
}
}
ReactDOM.render(<HOC />, document.getElementById('react-content'))
如果您的意见不同,请告诉我