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

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

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

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

Q&A

2回答

2691閲覧

javascriptのエラー原因がわからない

babbleman

総合スコア107

JavaScript

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

0グッド

0クリップ

投稿2020/01/23 03:15

編集2020/01/23 03:18

javascript

1class sample{ 2 searchavailavle(){ 3 var arr=[] 4 for(var i=0;i<8;i++){ 5 for(var j=0;j<8;j++){ 6 if(this.isavailable([i,j])){ 7 arr.push([i,j]) 8 } 9 } 10 } 11 return arr 12 } 13 14 randomput(){ 15 var arr=this.searchavailavle(); 16 var randnum = Math.floor( Math.random() * arr.length ) 17 console.log(arr); 18 this.putstone(arr[randnum])} 19 20 21 22 check(id){ 23 var y=parseInt(id/10) 24 var x=id%10 25 this.putstone([y,x]) 26 setTimeout(this.randomput(),1000);//←該当の問題箇所 27 } 28 29} 30var x=new Board(8); 31x.check(24)

上記のようなコード(一部抜粋)を書いたのですが、これを実行すると下記のようなエラーが発生します

timers.js:121 throw new ERR_INVALID_CALLBACK(callback); ^ TypeError [ERR_INVALID_CALLBACK]: Callback must be a function. Received undefined

これはthis.randomput()が関数ではないよ、ということらしいのですがネットで情報を調べていたところかっこを外せばいいということらしいので(なぜカッコを外すと別の何かになるのかも知りたいですが)おそらく関数の戻り値をそのままsetTimeoutに入れてしまってるんだろうな、と想像しながら下記のようにコードを変えてみました。

javascript

1setTimeout(this.randomput,1000);

すると今度は

var arr=this.searchavailavle(); ^ TypeError: this.searchavailavle is not a function

のように出てきてしまいました。
関数の中で関数を呼び出しているだけなのになぜこのようなエラーがおこるのでしょうか?
ちなみに、setTimeoutで括らないと普通に即時実行されます。
2日くらいこの問題に向き合ってますが一向に解決できません。
お助けのほどよろしくお願い申し上げます。

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

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

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

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

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

kei344

2020/01/23 03:20

「コードを変えてみました」と有りますが、コードが変わっていないようです。
guest

回答2

0

setTimeout(()=>this.randomput(),1000)ではどうでしょう?

投稿2020/01/23 03:19

quzq

総合スコア185

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

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

babbleman

2020/01/23 03:23

いけました!!なぜでしょう。 自分も関数にしないといけないのかなと思いまして下記のように変えてみたりもしましたが駄目でした。 setTimeout(function(){this.randomput()},1000)
miyabi-sun

2020/01/23 03:35

`function(){}`で包むと新しくthisが作られるので randomputメソッド内で「this.xxxなんて存在しないじゃないか!」と叱られます ES2015という新しい仕様で追加された`() => {}`というアロー関数は thisを生成しないのでメソッド内で使い回すにはとても使い勝手が良いものになります。 this束縛が切れるあたりの話は私の回答も見て下さいね。
guest

0

setTimeout(this.randomput(),1000);

変数等の後にカッコをつけるのは、
JavaScriptに於いては「関数・メソッドの実行」を意味します。

このrandomputメソッドを実行するタイミングはsetTimeoutによる1000ミリ秒後想定ですよね?
ならば今実行してはいけません。

setTimeout(this.randomput,1000);のようにカッコ無しに変更することで
setTimeoutの中の処理の方が引数の関数を1秒後に勝手に実行してくれるようになります。

this.searchavailavle is not a function

setTimeout(this.randomput,1000);に変更したことで
thisの束縛が剥がれた事が原因です。

JSの関数は引数に関数やメソッドを投げ込んで後から実行が出来る言語です。
しかし、メソッドをこのように引数として他人に受け渡してしまうとthisの束縛が切れてしまいます。

JavaScriptでは関数とメソッドの違いが明確には区切られて無く
同じFunctionオブジェクトを関する同じものです。
なのでthisを束縛するbindメソッドが用意されています。

デモの部分が英語で「うっ……」となりそうなので翻訳

js

1// オブジェクトを宣言しておく 2// 動作的にはクラス・インスタンスとほぼ同じになるので再現するだけならこれで十分 3const module = { 4 x: 42, 5 getX: function() { 6 return this.x; 7 } 8} 9 10// 質問文は関数の引数として利用したが、 11// 変数にメソッドを束縛してもthisが切り離されてしまう 12const unboundGetX = module.getX; 13console.log(unboundGetX()); 14// undefined 15 16// thisはこれなんだよと明示してあげる 17const boundGetX = unboundGetX.bind(module); 18console.log(boundGetX()); 19// 42 <- module.xの数値が正しく取り出せた

これと同じでこのようにすれば動きます。
setTimeout(this.randomput.bind(this), 1000);

投稿2020/01/23 03:32

編集2020/01/23 10:38
miyabi-sun

総合スコア21158

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

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

babbleman

2020/01/23 03:51

なるほど!関数の所有権の問題だったんですね。下のコメントの方も拝見させて頂きましたが、javascriptでは関数もオブジェクトとして扱っており、(確か元々class構文がなくfunctionで代替していたとみた事があります)新しいオブジェクトとして作られてしまったと言うことなんですね。アロー関数は完全にメソッドとしてなっておりオブジェクトを生成しない、と言う認識ですね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問