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

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

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

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

Q&A

解決済

3回答

1685閲覧

JavaScriptでインスタンスのメソッドを3項演算子で分岐するとthisがundefinedになる

kgtkr

総合スコア49

JavaScript

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

0グッド

0クリップ

投稿2016/08/19 16:07

JavaScript

1class Hoge{ 2 func1(){ 3 console.log(this); 4 } 5 func2(){ 6 console.log(this); 7 } 8} 9 10var h=new Hoge(); 11h.func1(); 12h.func2(); 13 14var flag=true; 15(flag?h.func1:h.func2)(); 16 17var flag=false; 18(flag?h.func1:h.func2)();

と実行するとlogに、

Hoge{} Hoge{} undefined undefined

と出力されます。
実行している内容は上2つと下2つで同じと思うのですが何故こうなるのでしょうか?

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

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

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

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

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

guest

回答3

0

ベストアンサー

こういうのと同じですね。
functionのコンテキストが変わったので、thisにバインドされているものが変わったと言いますか。

javascript

1var c = function(){} 2c.x = function(){console.log(this.toString());} 3c.x(); 4// "function (){}" 5var fx = c.x; 6fx(); 7// "[object Window]" 8 9var d = function(){} 10var fy = function(){console.log(this.toString());} 11fy(); 12// "[object Window]" 13d.y = fy; 14d.y(); 15"function (){}"

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/this

のメソッドの束縛のところ。

ここからわかるように、bar は foo とは何のつながりもありません。オブジェクトは関数を参照するプロパティを持つ事が出来ますが、その関数はそのオブジェクトに所属 している訳ではありません。具体的に言うと、この関数内の this は getBrand の定義時に自動的に foo に置き換えられるわけではありません。そうではなく、this は関数の呼び出し元から与えられます。つまり、foo.getBrand() という式によって、foo が this として foo.getBrand に参照される関数に渡されるということです。

以下の様にbindしておけば、期待する結果となります。

javascript

1class Hoge{ 2 get a(){ 3 return "a"; 4 } 5 get _func1(){ 6 return this.func1.bind(this); 7 } 8 func1(){ 9 console.log(this.a); 10 } 11 func2(){ 12 console.log(this); 13 } 14} 15 16var h=new Hoge(); 17h.func1(); 18// a 19h.func2(); 20// Hoge {} 21 22 23var flag=true; 24var f = h._func1; 25// h._func1によって、thisがhの状態で実行され、結果func1にhがbindされたものがfに入る。 26f(); 27// a 28(flag?h.func1.bind(h):h.func2.bind(h))(); 29// a 30var flag=false; 31(flag?h.func1:h.func2)(); 32// undefined 33 34 35var f2 = h.func2; 36f2(); // undefined - ここでWindowでないのは私もまだきっちり説明できない 37window.f2(); // Window

投稿2016/08/19 17:04

flied_onion

総合スコア2604

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

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

kgtkr

2016/08/20 01:03

関数はオブジェクトに所属していると思い込んでいました。 呼び出し元からthisが与えられていたのですね。 分かりやすい回答ありがとうございました。
guest

0

js

1(flag?h.func1:h.func2)();

これは 即時関数になっており,スコープが変わり別スコープで(外側で)定義された flag および h に参照することができません.

undefined という出力は,おそらくデベロッパーツールで実行した時のものであり,console.log によって出力されたものではなく,実行した関数の返却値を出しているものです.

投稿2016/08/19 16:14

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

kgtkr

2016/08/19 16:30

実際はfunc1内では this.hoge=foo; のような事をしていたのですが、エラーが出た為thisを出力してみた所undefinedが出力されました。 そこで三項演算子を if(flag){ h.func1(); }else{ h.func2(); } と言う風にif文に書き換えて実行して見ると正常に動きました。 その為undifineはおそらくlogの出力によるものだと思います。
guest1213

2016/08/19 16:35

外側のhもflagも参照できるし、出力もconsole.logによるものだと思います。
guest

0

(flag?h.func1:h.func2)();はflagによらず結局は以下と同じだからだと思います。

JavaScript

1(function() { 2 console.log(this); 3})();

h.func1(またはfunc2)と同じ内容で即時間数を定義して実行しているだけなのでthisはそのコンテキストに依存します。ちなみにブラウザ上で実行したらWindowでした。

あまり明確な仕様は知りませんが、へーなるほどなあと思いました。

投稿2016/08/19 16:32

guest1213

総合スコア306

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問