[解決済み] Uncaught TypeError: 未定義のプロパティ '0' を設定できない "
質問
エラーが発生しました。
Uncaught TypeError: 未定義のプロパティ '0' を設定できません。
この行では、なぜか
world_map_array[i][z]="grass.gif|ongrass.gif|collision.gif|above.gif";
なぜこのようなことが起こるのでしょうか?
よろしくお願いします
var x_world_map_tiles = 100;
var y_world_map_tiles = 100;
var world_map_array = new Array(x_world_map_tiles);
for (i=0; i<=2; i++)//create a two dimensional array so can access the map through x and y coords map_array[0][1] etc.
{
world_map_array[i]=new Array(y_world_map_tiles);
}
for (i=0; i<=x_world_map_tiles; i++)//just a test
{
for (z=0; z<=y_world_map_tiles; z++)//just a test
{
world_map_array[i][z]="grass.gif|ongrass.gif|collision.gif|above.gif";
}
}
解決方法は?
JavaScriptの配列は、他の言語から来た人には思いもよらないような癖があります。あなたのユースケースにとって重要なものは2つあります。
- JavaScriptでは多次元配列を直接宣言することはできません。
- 配列の作成時にサイズを設定しても、効率的な利点はほとんどありません (安全性の向上もありません)。
他の言語と違って、JavaScriptは配列全体に対してメモリブロックを割り当てることはありません。
(各セルにどのようなオブジェクトを入れるのかが分からないのです。
したがって、合計でどれくらいのメモリが必要になるのでしょうか)。
その代わり、すべての
size
の引数を
Array()
は、配列の
length
プロパティがあります。
一般的な2次元配列の場合なら
-
例えば、"top"配列を作成します。
var i // the first-order index in a , j // the second order index in a , a = []
-
必要に応じて、配列の要素を初期化します。 これは 遅延初期化 , をテストすることであり、この場合、単純に
a[i]
存在する に何かを代入しようとする前にa[i][j]
, 例:if (!a[i]) a[i] = []
上記の文章を英語にするとこうなる。 もし
a
が 'falsy' である場合、i番目の要素に空の配列を代入します。 -
最後に、多項目配列に実際の値を代入する。
a[i][j] = 'whatever'
あなたの場合は、先に値がわかっていますね。 ということで、各要素をあらかじめ初期化しておくことができます。 (ただし、ほとんどの要素をオーバーライドしないのであれば。 のような遅延実装の方がよいかもしれません; 下記参照)。
var x, x_length = 100
, y, y_length = 100
, map = []
// Don't be lazy
for (x = 0; x < x_length; x++) {
map[x] = []
for (y = 0; y < y_length; y++) {
map[x][y] = 'grass.gif|ongrass.gif|collision.gif|above.gif'
}
}
他の方もおっしゃっていますが 100個の要素を持つ配列のインデックスには、以下の番号が振られます。 ゼロ から 九十九 , ということで、ここでは小差の比較が最も適切である。
参考までに、遅延初期化を利用した実装を紹介します。 配列に直接アクセスするのではなく、関数のインターフェイスを使っています。 より長く、より複雑ですが、より完全です。
ここで使った初期化パターンは 即座に呼び出される関数式 . 見たことがない人は JavaScriptの便利なパターンの1つです。 時間をかけて理解する価値があります。
var map = (function (x_length, y_length, v_default, undefined) {
// Unless v_default is overwritten, use ...
v_default = v_default || 'grass.gif|ongrass.gif|collision.gif|above.gif'
// Private backing array; will contain only values for a[x][y]
// that were explicitly set.
var a = []
// Private helper function.
// - Returns `true` if `x` is between `0` and `x_length - 1`
// and `y` is between `0` and `y_length - 1`.
// - Returns `false` otherwise.
function valid (x, y) {
return (x >= 0
&& x < x_length
&& y >= 0
&& y < y_length)
}
// Private helper function.
// - Returns `true` if a[x][y] has been set().
// - Returns `false` otherwise.
function exists (x, y) {
return !!a[x] && !!a[x][y]
}
// Private getter
// - Returns the value of a[x][y] if it has been set().
// - Returns `undefined` if the point (x,y) is invalid.
// - Returns `v_default` otherwise.
function get (x, y) {
if (!valid(x, y)) return undefined
else if (exists(x, y)) return a[x][y]
else return v_default
}
// Private setter
// - Returns the value set on success.
// - Returns `undefined` on failure
function set (x, y, v) {
if (valid(x, y)) {
// We're being lazy
if (!a[x]) a[x] = []
a[x][y] = v
return a[x][y]
}
return undefined
}
// Return an interface function.
// - Pass the function three arguments, (x, y, v), to set a[x][y] = v
// - Pass the function two arguments, (x, y), to get a[x][y]
return function (x, y, v) {
if (arguments.length > 2) {
return set(x, y, v)
} else {
return get(x, y)
}
}
})(100, 100)
上記をnodeで実行したところ、以下のようなテストが感覚的な値を出力しました。
// Invalid invocations
console.log('map() : %s', map())
console.log('map( 0) : %s', map(0))
console.log('map( -1, 0) : %s', map(-1,0))
console.log('map( 0, -1) : %s', map(0, -1))
console.log('map( -1, -1) : %s', map(-1, -1))
// Valid invocations
console.log('map( 0, 0) : %s', map(0, 0))
console.log('map( 99, 99) : %s', map(99, 99))
console.log('map( 1, 1) : %s', map(1,1))
console.log('map( 1, 1, "foo") : %s', map(1,1, 'foo'))
console.log('map( 1, 1) : %s', map(1,1))
関連
-
[解決済み] Uncaught TypeError: 未定義のプロパティ 'top' を読み込めない
-
[解決済み】エラー:リスン EACCES 0.0.0.0:80 OSx Node.js
-
[解決済み] JavaScript - 未定義のプロパティを設定することはできません。
-
[解決済み] JavaScriptで空文字列/未定義文字列/null文字列をチェックするにはどうすればよいですか?
-
[解決済み] JavaScriptでNULL、未定義、空白の変数をチェックする標準的な関数はありますか?
-
[解決済み] 変数が「未定義」または「NULL」であるかどうかを判断するにはどうすればよいですか?
-
[解決済み] JavaScriptで配列の長さを初期化する方法は?
-
[解決済み】オブジェクトの配列を文字列のプロパティ値でソートする
-
[解決済み】未定義のオブジェクトプロパティを検出する
-
[解決済み】JavaScriptの関数にデフォルトのパラメータ値を設定する
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】TypeError: $(...).DataTable は関数ではありません。
-
[解決済み】Uncaught ReferenceError: angular is not defined - AngularJSが動作しない。
-
[解決済み】webpack: モジュールが見つかりません。Error: 解決できない(相対パスで)
-
[解決済み】JavaScriptのinnerHTMLで要素が更新されない
-
[解決済み】SyntaxError: ChromeのJavascriptコンソールでUnexpected Identifierが発生する。
-
[解決済み】Uncaught SyntaxError: JSON の位置 0 に予期しないトークン u があります。
-
[解決済み】ETIMEDOUTエラーの対処方法は?
-
[解決済み】JavaScriptで関数が存在するかどうかを確認する方法は?
-
[解決済み】Vueが定義されていない
-
[解決済み】react router v^4.0.0 Uncaught TypeError: 未定義のプロパティ'location'を読み取れない