ES范例解读之自增操作符

ES范例解读之自增操纵符

原文:https://github.com/kuitos/kuitos.github.io/issues/24
几个月前,不知道什么启事跟同事议论了起js里自增操纵符(i++)的题目,现将来龙去脉整理出来,传于众人?

事变起源于如许一段代码

var i = 0;
i = i++;
console.log(i);

来,都来说说答案是啥?
效果是0
换一种情势,也许人人不会有若干疑问

var i = 0;
var a = i++;
console.log(a); // 0

没错,这也是我们初学自增操纵符的典范例子,对这效果另有疑问请自发面壁。。。
遐想昔时进修自增操纵符的口诀大抵是,i++ 是先用后自增,++i 是先自增再用
那末根据这个思绪,上面的代码剖析流程应该是如许的

var i =0;
i = i;
i = i + 1;

惋惜效果并非如许的
根据犀牛书上的形貌,后增量(post increment)操纵符的特点是

它对操纵数举行增量盘算,但返回未作增量盘算的(unincremented)值。

然则书上并没有通知我们,先做增量盘算再返回之前的值,照样返回之前的值再做增量盘算。
关于这类疑问,我们只能乞助ecmascript给出官方诠释:

Postfix Increment Operator(后自增操纵符)

The production PostfixExpression : LeftHandSideExpression [no LineTerminator here] ++ is evaluated as follows:

  1. Evaluate LeftHandSideExpression.

  2. Call GetValue(Result(1)).

  3. Call ToNumber(Result(2)).

  4. Add the value 1 to Result(3), using the same rules as for the + operator (see 11.6.3).

  5. Call PutValue(Result(1), Result(4)).

  6. Return Result(3).

从es上的算法形貌,我们能够清楚的得知,后自增操纵符是先自增赋值,然后返回自增前的值,如许的一个递次。
到这里还不算完。
既然i=i++这类操纵末了i照样为原始值,也就是这段代码不会有任何实际意义,那末js引擎有无能够针对性的做优化,从而防止不必要的自增运算?(假如你用的是IDE,IDE会提醒你这是一段无用的代码)
也就是说,我们怎样肯定,实行引擎肯定做了两步操纵:

  1. i = i + 1; return iBeforeIncrease = 0;

  2. i = iBeforeIncrease;

照样实行引擎能够会针对性的优化,只做一步操纵:

  1. i = iBeforeIncrease;

当我在想怎样去肯定这一点时,松波给出了解决方案,用Object.observe()要领啊!!(该要领是ES7提案中的新api,不过chrome早早的完成了)

var obj = {i:0};
Object.observe(obj, function(changes){
    console.log(changes);
});
obj.i = obj.i++;

代码放到chrome中跑一下,能够看到,转变触发了两次,也就是i做了两次修正操纵
别的firefox中也供应了一个相似的api,Object.prototype.watch,有兴致的同砚能够试试用这个体式格局来考证一下。

趁便抖个灵巧,自增操纵黑白原子性操纵,黑白线程平安的,多线程环境下共用变量运用自增操纵符是会有题目的(前端同砚们别急,ES7会为我们带来js多线程编程体验?)。

    原文作者:kuitos
    原文地址: https://segmentfault.com/a/1190000003785340
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞