質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

5回答

1119閲覧

ヌル合体代入演算子(??=)のMDNの記述について

Lhankor_Mhy

総合スコア36960

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

1グッド

4クリップ

投稿2020/07/10 07:21

Logical nullish assignment (??=) - JavaScript | MDN

↑こちらについて、

ヌル合体代入演算子の短絡評価は、つまり x ??= y が次の式と等価であることを意味します:

js

1x ?? (x = y);

そして、次の式とは必ずしも等価になるとは限りません:

js

1x = x ?? y;

という記述があります。(当方による勝手訳)

この後段について等価とならないケースがイメージできないので、教えてください。
セッタが評価されるかどうか、ということなのかな? とは思ったのですが、正しいでしょうか?
その他のケースも考えられますか?

yohhoy👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答5

0

ベストアンサー

xが単なる変数なら違いはなさそうですが、セッターのあるプロパティにa.b ??= 5;のようにした場合、セッターの実行回数が違ってくる、ように思われます(ちょっと自信はないです)。

投稿2020/07/10 07:28

編集2020/07/10 07:29
maisumakun

総合スコア146018

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Lhankor_Mhy

2020/07/10 08:27

やはりですか。 セッタの実行回数が大きな影響を与えるようなケースを思いつかなかったので、あまり気にすることはないですかね……?
maisumakun

2020/07/10 08:29

文法的には実装できますけど、「セッターが副作用を持つ」ようなオブジェクトは(デバッグ出力を行う程度なら別ですが)むしろ嫌がらせに近い存在でしょうしね…
Lhankor_Mhy

2020/07/10 10:28

いろいろググってたらこんなのが。 https://v8.dev/features/logical-assignment なるほど、innerHTMLね、と思いました。 というか、DOMのプロパティは副作用が多そうなので、他にも何かあるかもしれません。
maisumakun

2020/07/10 10:41

> DOMのプロパティは副作用が多そうなので 参照だけでリフローがかかる寸法系プロパティとか、けっこうな魔境ですね。
guest

0

それでいいのでは?

セッタが評価されるかどうか、ということなのかな?

投稿2020/07/10 07:37

x_x

総合スコア13749

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

x_x

2020/07/10 07:39

わたしも仕様を追っているわけではないのでそうだろうなーとしか言えません。 最近はろくにログインすらしてないので、たまたま回答依頼に気づいて答えています。 think49 さんが的確な回答をしてくれるのではないかと期待しています。
Lhankor_Mhy

2020/07/10 08:27

ありがとうございます、お呼びだてして失礼しました。 (一応、ログイン時間は確認したつもりでした) 他の方の回答をもう少しお待ちしたいと思います。
guest

0

リンク先にある "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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Lhankor_Mhy

2020/07/10 10:23

ありがとうございます。おっしゃるとおりかと思います。
guest

0

CoffeeScriptRubyにはかなり昔からあったので、私は何の疑問も思わないのですが、代入の評価という物を考えると違いがはっきりします。

現在の所、対応ブラウザのバージョンは開発版しかないようなので、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
raccy

総合スコア21739

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Lhankor_Mhy

2020/07/10 10:25

ありがとうございます。Babelでは同様のことを試していましたが、そういうことなのか確信が持てず。 やはりそういうことなんですね。
guest

0

x ?? (x = y);

これは単にx ?? yをしつつ、xにyを代入しているだけです

投稿2020/07/10 07:26

yambejp

総合スコア116724

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maisumakun

2020/07/10 07:36 編集

??演算子はショートサーキットなので、xがnullishでない場合は代入は行われません。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問