Logical nullish assignment (??=) - JavaScript | MDN
↑こちらについて、
ヌル合体代入演算子の短絡評価は、つまり
x ??= y
が次の式と等価であることを意味します:
js
1x ?? (x = y);
そして、次の式とは必ずしも等価になるとは限りません:
js
1x = x ?? y;
という記述があります。(当方による勝手訳)
この後段について等価とならないケースがイメージできないので、教えてください。
セッタが評価されるかどうか、ということなのかな? とは思ったのですが、正しいでしょうか?
その他のケースも考えられますか?
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
下記のような質問は推奨されていません。
- 質問になっていない投稿
- スパムや攻撃的な表現を用いた投稿
適切な質問に修正を依頼しましょう。
回答5件
4
ベストアンサー
x
が単なる変数なら違いはなさそうですが、セッターのあるプロパティにa.b ??= 5;
のようにした場合、セッターの実行回数が違ってくる、ように思われます(ちょっと自信はないです)。
投稿2020/07/10 07:28
編集2020/07/10 07:29総合スコア142240
3
それでいいのでは?
セッタが評価されるかどうか、ということなのかな?
投稿2020/07/10 07:37
総合スコア13733
下記のような回答は推奨されていません。
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
このような回答には修正を依頼しましょう。
回答へのコメント
2
リンク先にある "And not equivalent to the following which would always perform an assignment:" は、「常に代入を行う次のもの (x = x ?? y;
という文) とは異なります」という意味と思われるので、
JavaScript
1x = x ?? y;
は、xがnullかundefinedでなければxにxが代入されますが、
??= を使用する場合はxにxを代入するなんてことはしない、という意味ではないでしょうか。
投稿2020/07/10 10:17

退会済みユーザー
総合スコア0
下記のような回答は推奨されていません。
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
このような回答には修正を依頼しましょう。
回答へのコメント
1
CoffeeScriptやRubyにはかなり昔からあったので、私は何の疑問も思わないのですが、代入の評価という物を考えると違いがはっきりします。
現在の所、対応ブラウザのバージョンは開発版しかないようなので、CoffeeScriptでやってみます。
CoffeeScript
1obj = 2 get: 0 3 set: 0 4 _x: undefined 5 reset: -> 6 this.get = 0 7 this.set = 0 8 this._x = undefined 9Object.defineProperty obj, 'x', 10 get: -> 11 this.get++ 12 this._x 13 set: (val) -> 14 this.set++ 15 this._x = val 16 17obj.reset() 18obj._x = undefined 19obj.x ?= 1 20console.log obj.get, obj.set 21 22obj.reset() 23obj._x = 0 24obj.x ?= 1 25console.log obj.get, obj.set 26 27obj.reset() 28obj._x = undefined 29obj.x = obj.x ? 1 30console.log obj.get, obj.set 31 32obj.reset() 33obj._x = 1 34obj.x = obj.x ? 1 35console.log obj.get, obj.set
2番目だけsetがカウントされません。
CoffeeScriptなんてマイナーなAltJSは知らない!という人のためにECMAScriptで書き直しました。
ECMAScript
1const obj = { 2 get: 0, 3 set: 0, 4 _x: void 0, 5 reset: function() { 6 this.get = 0; 7 this.set = 0; 8 this._x = void 0; 9 }, 10 get x() { 11 this.get++; 12 return this._x; 13 }, 14 set x(val) { 15 this.set++; 16 return this._x = val; 17 } 18}; 19 20obj.reset(); 21obj._x = void 0; 22obj.x ??= 1; 23console.log(obj.get, obj.set); 24 25obj.reset(); 26obj._x = 0; 27obj.x ??= 1; 28console.log(obj.get, obj.set); 29 30obj.reset(); 31obj._x = void 0; 32obj.x = obj.x ?? 1; 33console.log(obj.get, obj.set); 34 35obj.reset(); 36obj._x = 1; 37obj.x = obj.x ?? 1; 38console.log(obj.get, obj.set);
Babelで変換して実行すれば、同じ結果が得られるのが分かると思います。
なお、tc39にあるこの機能の提案に書いてあるとおり、Ruby(2003年の1.8.0には既にあった、というより1995年の初期リリースからかも?)、CoffeeScript(2010年の0.2.6から)、C#(2019年の8.0から)の機能を参考にしています。プロパティに対するゲッターとセッターがメソッドではなく参照と代入として書くスタイルの言語では特に新しくもなんともない機能です。
投稿2020/07/10 10:11
編集2020/07/10 10:31総合スコア21697
下記のような回答は推奨されていません。
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
このような回答には修正を依頼しましょう。
回答へのコメント
0
x ?? (x = y);
これは単にx ?? yをしつつ、xにyを代入しているだけです
投稿2020/07/10 07:26
総合スコア109923
下記のような回答は推奨されていません。
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
このような回答には修正を依頼しましょう。
回答へのコメント
2020/07/10 07:36 編集
関連した質問
Q&A
解決済
空白文字に挟まれた文字列を抜き出す正規表現(JavaScript)
回答3
クリップ0
更新
2023/03/27
Q&A
解決済
checkboxを使った絞り込み検索 or検索からand検索に変更
回答1
クリップ0
更新
2023/03/28
Q&A
解決済
省エネモデルのストップウォッチを作る
回答1
クリップ0
更新
2023/03/26
意見交換
受付中
プログラミングの設計が分からない
回答24
クリップ10
更新
2023/03/17
意見交換
クローズ
JSの変数名の先頭に$マークをつける理由
回答12
クリップ4
更新
2023/02/01
Q&A
解決済
Atcoder ABC294-DのTLEの解消方法を教えてください
回答2
クリップ1
更新
2023/03/22
Q&A
解決済
classNameの使い方と引数の中身について
回答2
クリップ1
更新
2023/03/23
意見交換
受付中
プログラマを目指す際の進路について
回答35
クリップ2
更新
2023/03/18
同じタグがついた質問を見る
JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。
下記のような回答は推奨されていません。
このような回答には修正を依頼しましょう。
2020/07/10 08:27
2020/07/10 08:29
2020/07/10 10:28
2020/07/10 10:41