ES規範解讀之自增操作符

2021-07-07 05:13:38 字數 2022 閱讀 8315

原文:

幾個月前,不知道什麼緣由跟松波同學討論了起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:

evaluate lefthandsideexpression.

call getvalue(result(1)).

call tonumber(result(2)).

add the value 1 to result(3), using the same rules as for the + operator (see 11.6.3).

call putvalue(result(1), result(4)).

return result(3).

從es上的演算法描述,我們能夠清晰的得知,後自增操作符是先自增賦值,然後返回自增前的值,這樣的乙個順序。

到這裡還不算完。

既然i=i++這種操作最後i還是為原始值,也就是這段**不會有任何實際意義,那麼js引擎有沒有可能針對性的做優化,從而避免不必要的自增運算?(如果你用的是ide,ide會提示你這是一段無用的**)

也就是說,我們如何確定,執行引擎一定做了兩步操作:

i = i + 1;return ibeforeincrease = 0;

i = ibeforeincrease;

還是執行引擎可能會針對性的優化,只做一步操作:

i = ibeforeincrease;

當我在想怎麼去確定這一點時,松波給出了解決方案,用object.observe()方法啊!!(該方法是es7提案中的新api,不過chrome早早的實現了)

var obj = ;

object.observe(obj, function

(changes));

obj.i = obj.i++;

**放到chrome中跑一下,可以看到,改變觸發了兩次,也就是i做了兩次修改操作

另外firefox中也提供了乙個類似的api,object.prototype.watch,有興趣的同學可以試試用這個方式來驗證一下。

順便抖個機靈,自增操作是非原子性操作,是非執行緒安全的,多執行緒環境下共用變數使用自增操作符是會有問題的(前端同學們別急,es7會為我們帶來js多執行緒程式設計體驗��)。

後置自增操作符與解引用,前置自增操作符

char a hello char p a int i strlen a while i 0 1 之前一直以為printf c p 這句話是先解引用再將p指標 的,但是我還是太年輕了,不然怎麼會有hello而不是ello呢?2 但是,運算子的優先順序顯示後置自增操作符 優先順序高於解引用 那麼輸出應...

自增 和自減 操作符

自增操作符和自減操作符經常要在我們自定義的類型別中使用到,而使用時經常會出現問題。現把自己在學習的過程中的 拿出來看一下,也是c primer中的例子如下 ifndef check ptr define check ptr include using namespace std class chec...

關於自增自減操作符

c c 中自增自減運算子相信是不少人的乙個困擾,這個問題也一直困擾著我,今天再次翻開書本來看了看,有了些新的體會,所以在這裡記錄下來,同時也與那些像我一樣被困擾的人分享,程式設計大牛可以繞道了,或者有什麼不對的地方請大牛們指正。以 為例,如下程式輸出結果是什麼 int a 0,j 1 a j cou...