HTML/JavaScript集 > JavaScriptメモ

JavaScriptメモ

変数のダンプを取得する

var myDump = function(obj /*, indent */){

	var  undefined;

	var indent = arguments.length > 1 ? arguments[1] : "";
	if (obj === null) {
		return "null";
	}
	if (obj === undefined) {
		return "undefined";
	}
	if ((typeof obj == "string") || (obj instanceof String)) {
		return obj.toString();
	}
	if ((typeof obj == "number") || (obj instanceof Number)) {
		return obj.toString();
	}
	if ((obj instanceof Array) || (obj instanceof Object)) {
		var dumpStr = "{\n";
		var subIndent = indent + "\t";
		for (var key in obj) {
			try {
				dumpStr += subIndent + key + "=" + myDump(obj[key], subIndent) + "\n";
			} catch (e){
				dumpStr += subIndent + key + "=" + subIndent + "unknown" + "\n";
				break;
			}
		}
		dumpStr += indent + "}";
		return dumpStr;
	}
	return "unknown";
};

文字列をJSONオブジェクトに変換

var text = '{"var1":"abc", "var2":10 }';
var obj = JSON.parse(text);
alert(obj.var1);       // abcと表示される
alert(obj.var2);       // 10と表示される

※文字列の外側の括りはシングルクォーテーション、JSONのキー名はダブルクォーテーションで括るのが良さげ。

JSONオブジェクトを文字列に変換

var obj = {"var1":"abc", "var2":10 };
var str = JSON.stringify(obj);
alert(str);

undefined や null の判定方法(typeof を使わない方法)

変数が undefined かどうかを判定するのによく使用されるのは「 typeof var1 === "undefined" 」というコードだが、
これは、以下の不具合を回避する為に、このような書き方が行われている。

(1) undefined が定数でなく変更可能な変数として定義されている為、undefined の中身が undefined でない可能性がある。
(2) 変数自体が未定義の場合にスクリプトエラーとなってしまう

ここでは typeof を使用せずに undefined の判定を行う方法を記載する。

undefined を使用しない書き方

// 以下は上記(2)の不具合は残っている状態
var var1;
if (var1) {
  alert("var1は定義済み");
} else {
  alert("var1は undefined、null、false、0 のどれか");
}

// 親オブジェクトがある場合は(2)の不具合も起きない
var ary = [1,2,3];
if (ary[10]) {
  alert("ary[10]は定義済み");
} else {
  alert("ary[10]はundefined、null、false、0 のどれか");
}

// Mapでも同様に親オブジェクトがあるので(2)の不具合は起きない
var obj = {"a":"A"};
if (obj["x"]) {
  alert("obj[x]は定義済み");
} else {
  alert("obj[x]はundefined、null、false、0 のどれか");
}

上記 var1 のケースで、以下のように変数そのものが未定義の場合には使用できない。

//var var1 = "xx";   // コメントアウト
if (var1) {                         // <- var1は宣言されていないのでスクリプトエラー
  alert("var1は定義済み");
} else {
  alert("var1はundefined、null、false、0 のどれか");
}

なので、どうしても typeof ・・ とか書きたくないなら、必ず存在する親要素を指定する。

if (window.var1){
  alert("var1は定義済み。");
} else {
  alert("var1はundefined、null、false、0 のどれか");
}

undefined のみを判定したい場合は、さらに undefined を自分で定義する方法もある(jQuery方式)

(function(){

    var undefined;      // 中身が undefined な変数を定義

    // 変数 undefined の中身は必ずundefined となる為、以下のコードでも正確に undefined の判定ができる
    if (window.var1 === undefined){
        alert("var1はundefined");
    }
})();

《結論》
Node.js 等のサーバサイドJavaScriptだと windowオブジェクト自体がないので、
変数は任意の名前空間配下に置くか、素直に typeof var1 === "undefined" とした方が良いかも。

クロージャ

var addCount = (function(){
	var val = 0;
	return function(){
		val = val + 1;
		return val;
	};
})();

var cnt = 0;
cnt = addCount();
console.log(cnt);
cnt = addCount();
console.log(cnt);

プロトタイプチェーンによる継承

// コンストラクタの定義
var Person = function(name, age){

    // インスタンス変数の初期化
    this.name = name;
    this.age  = age;

    /*  
    // 良くないメソッド定義1(Personインスタンス毎に関数オブジェクトが生成される)
    this.setAge = function(age){
        this.age = age;
    };

    //  良くないメソッド定義2(この方法でもメソッドは個々のオブジェクトに格納される)
    function setAge(age){
        this.age = age;
    };
    */
};
// インスタンス変数やメソッド定義はプロトタイプ指定しておく
Person.prototype.name = "unknown";
Person.prototype.age  = 0;
Person.prototype.setAge = function(age){
    this.age = age;
};
Person.prototype.dispInfo = function(){
    console.log("----- dispInfo -----");
    console.log(this.name + "(" + this.age + ")");
};

// 継承
var Man = function (name, age) {
    Person.call(this, name, age);  // 親オブジェクトのコンストラクタを呼び出し(Javaでの super() と同じ)
    this.sex = "MAN";
};
Man.prototype.sex = "?";
Man.prototype.dispInfo2 = function(){
    console.log("----- dispInfo2 -----");
    console.log(this.name + "(" + this.age + "," + this.sex +")");
};
Object.setPrototypeOf(Man.prototype, Person.prototype);    // プロトタイプとなるオブジェクトを指定

// 親クラスのインスタンス生成
var personObj = new Person("suzuki", 20);

// 継承クラスのインスタンス生成
var manObj = new Man("sato", 30);

// 継承クラスのインスタンスをコンストラクタを指定せずに生成
var manObj2 = Object.create(Man.prototype);

// 結果表示
personObj.dispInfo();
manObj.dispInfo();
manObj.dispInfo2();
manObj2.dispInfo();
manObj2.dispInfo2();

// クラスのプロパティを全表示
console.log("--- personObj -------------------------------");
for (var propName in personObj) {
    console.log(propName + " = " + personObj[propName]);
}
console.log("--- manObj -------------------------------");
for (var propName in manObj) {
    console.log(propName + " = " + manObj[propName]);
}
console.log("--- manObj2 -------------------------------");
for (var propName in manObj2) {
    console.log(propName + " = " + manObj2[propName]);
}

実行結果

----- dispInfo -----
suzuki(20)
----- dispInfo -----
sato(30)
----- dispInfo2 -----
sato(30,MAN)
----- dispInfo -----
unknown(0)
----- dispInfo2 -----
unknown(0,?)
--- personObj -------------------------------
name = suzuki
age = 20
setAge = function (age){
	this.age = age;
}
dispInfo = function (){
	console.log("----- dispInfo -----");
	console.log(this.name + "(" + this.age + ")");
}
--- manObj -------------------------------
name = sato
age = 30
sex = MAN
dispInfo2 = function (){
	console.log("----- dispInfo2 -----");
	console.log(this.name + "(" + this.age + "," + this.sex +")");
}
setAge = function (age){
	this.age = age;
}
dispInfo = function (){
	console.log("----- dispInfo -----");
	console.log(this.name + "(" + this.age + ")");
}
--- manObj2 -------------------------------
sex = ?
dispInfo2 = function (){
	console.log("----- dispInfo2 -----");
	console.log(this.name + "(" + this.age + "," + this.sex +")");
}
name = unknown
age = 0
setAge = function (age){
	this.age = age;
}
dispInfo = function (){
	console.log("----- dispInfo -----");
	console.log(this.name + "(" + this.age + ")");
}

添付ファイル: filetest.html 319件 [詳細]

トップ   差分 バックアップ リロード   一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2013-04-14 (日) 22:05:51 (4201d)