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

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

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

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

Q&A

解決済

3回答

3102閲覧

javascriptでテトリスを作っています。

tkkawachann

総合スコア15

JavaScript

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

0グッド

0クリップ

投稿2015/10/17 05:31

プログラミング初心者です。

参考書と全く同じように記述しているのですが、

cells[top0*width+0].style.backgroundColor='' の部分で
Uncaught TypeError: Cannot read property 'style' of undefinedとエラーが出ています。

エラーの原因について詳しく教えて下さい。
よろしくお願いします。


<html> <head> <meata charset="UTF-8"> <title>テトリス</title> <style type="text/css"> table{ border-collapse:collapse; } table td{ width:20px;height:20px;border:1px solid black; } </style> <script type="text/javascript"> window.onload =function(){ var width= 10 var height= 20 var html=['<table>']
for(j=0;j<height;j++){ html.push('<tr>') for(i=0;i<width;i++){ html.push('<td></td>') document.getElementById('view').innerHTML=html.join('') } html.push('</tr>') } html.push('</table>') var cells=document.getElementsByTagName('td') var top=0 var top0=top var move= function changestyle(){ ****cells[top0*width+0].style.backgroundColor=''**** cells[top0*width+1].style.backgroundColor='' cells[top0*width+2].style.backgroundColor='' cells[top0*width+3].style.backgroundColor='' cells[top*width+0].style.backgroundColor='red' cells[top*width+1].style.backgroundColor='red' cells[top*width+2].style.backgroundColor='red' cells[top*width+3].style.backgroundColor='red' var top0= top top++ if(top < height)setTimeout(move,1000) } move() }
</script> </head> <body> <div id="view"></div> </body> </html>

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

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

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

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

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

guest

回答3

0

なんらかのソースコードチェック機能があるエディタをつかうようにするとよいとおもいます。
↓は atom というエディタで jaascript のチェック機能を有効にさせてみたときの画面です。
イメージ説明
赤丸がついている行に問題があることがわかります。
これらの問題をすべて解決させたのが↓の画面です。
イメージ説明

jsdoit で実際に html と組み合わせて動作させてみました。
http://jsdo.it/katoy/WGqW
イメージ説明

投稿2015/10/17 10:06

katoy

総合スコア22324

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

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

katoy

2015/10/17 10:16

変更したファイルを js2cofee で coffeescript に変更しようとしてみたら、次の警告がでました。 modify.js:19:19:15: [warning] Named function expressions are not supported in CoffeeScript modify.js:6:6:9: [warning] Assignment of global variable 'j' modify.js:8:8:13: [warning] Assignment of global variable 'i' i, j の変数に var 宣言がなくてグローバル変数になっていることが判明しました。 var i, j; としたほうがよいです。
guest

0

ベストアンサー

とりあえず、期待した動作をさせるために修正すべき箇所は一つです。
move()関数内でvar top0= topとしている所をtop0=topに変更しましょう。

lang

1 var move= function changestyle(){ 2 cells[top0*width+0].style.backgroundColor='' 3 cells[top0*width+1].style.backgroundColor='' 4 cells[top0*width+2].style.backgroundColor='' 5 cells[top0*width+3].style.backgroundColor='' 6 cells[top*width+0].style.backgroundColor='red' 7 cells[top*width+1].style.backgroundColor='red' 8 cells[top*width+2].style.backgroundColor='red' 9 cells[top*width+3].style.backgroundColor='red' 10 top0= top // <- ここ 11 top++ 12 if(top < height)setTimeout(move,1000) 13}

恐らく期待した動作になっていると思います。

javascriptでは関数毎にスコープがあり、
var xxx...と宣言した変数は、それを宣言した関数の内側でのみ有効です。

関数内で変数を参照する際、外側で定義したものと同名の変数を内側でで宣言していた場合は
関数内で定義した変数の方が参照されるため、以下のような挙動になります

var a = 0; var b = top; // この動作は当たり前 alert(a); // alert 0 alert(b); // alert 0 var test = function () { var b = 1;// ここで b を宣言し、値 1 を代入。 alert(a); // alert 0 (外側のaを参照) alert(b); // alert 1 (関数内で宣言したbを参照) }; test();

更に、javascriptでは関数内で宣言した変数は全て最初に定義される(※代入は別です)ため、

lang

1var test = function () { 2 alert(b); 3 var b = 1; 4 alert(b); 5}; 6test();

上のようなコードは

lang

1var test = function () { 2 var b; // 変数宣言 3 alert(b); // 値は代入していないので初期値のundefined 4 b = 1; // 1 を代入 5 alert(b); // alert 1 6}; 7test();

と同等の挙動をします。

この仕様により、move()関数内でvarを付けて宣言された変数top0
最初のcells[top0*width+0].style.backgroundColor=''の時点では値はundefinedとなり、
top0*width+0部分が正しく計算できないため数でないことを表すNaNという特殊な値になります。
配列cellsにNaNは定義されていないため、cells[NaN]はundefinedになり、
undefinedからstyleというプロパティを参照しようとしたため
Uncaught TypeError: Cannot read property 'style' of undefinedというエラーが出たというわけです。

参考URL:
JavaScript のスコープを理解する
知らないと怖い「変数の巻き上げ」とは?

投稿2015/10/17 07:39

MAGP

総合スコア153

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

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

MAGP

2015/10/17 07:44

おっとcellsは厳密には配列ではないですね、失礼。
tkkawachann

2015/10/17 12:36

丁寧に質問に答えていただきありがとうございます。 エラーの原因の根本まで解説いただき、非常に助かりました!
guest

0

var top0 = topが2箇所あるのが問題です。2個目はvarが不要です。

javascript

1 var cells=document.getElementsByTagName('td') 2 var top=0 3 var top0=top 4 5 var move= function changestyle(){ 6/* … */ 7 // var top0= top 8 top0= top 9 top++ 10 if(top < height)setTimeout(move,1000) 11 } 12 move() 13 }

今回の場合、varが2個あるせいで下記みたいに扱われていたはずです。

javascript

1 var move= function changestyle(){ 2 var top0 = undefined 3/* … */ 4 top0= top 5/* … */ 6 } 7 move() 8 }

投稿2015/10/17 07:27

MIURA_Yasuyuki

総合スコア306

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問