[[HTML/JavaScript集]] > JavaScriptメモ
* JavaScriptメモ [#d10cc88d]
#setlinebreak(on);

#contents();

//** javascript クリップボード コピー
//** Dateオブジェクト(JavaScript)
//** 変数のデータ型を調べる(JavaScript)
//** 全角半角チェック(JavaScript)

** 変数のダンプを取得する [#i185f5c5]
#mycode{{
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オブジェクトに変換 [#ge275fba]
#mycode{{
var text = '{"var1":"abc", "var2":10 }';
var obj = JSON.parse(text);
alert(obj.var1);       // abcと表示される
alert(obj.var2);       // 10と表示される
}}
#html(<div style="padding-left:10px;">)
※文字列の外側の括りはシングルクォーテーション、JSONのキー名はダブルクォーテーションで括るのが良さげ。
#html(</div>)

** JSONオブジェクトを文字列に変換 [#u8725415]
#mycode{{
var obj = {"var1":"abc", "var2":10 };
var str = JSON.stringify(obj);
alert(str);
}}

** undefined や null の判定方法(typeof を使わない方法) [#x126a3df]

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

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

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

undefined を使用しない書き方
#mycode{{

// 以下は上記(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 のケースで、以下のように変数そのものが未定義の場合には使用できない。
#mycode{{
//var var1 = "xx";   // コメントアウト
if (var1) {                         // <- var1は宣言されていないのでスクリプトエラー
  alert("var1は定義済み");
} else {
  alert("var1はundefined、null、false、0 のどれか");
}
}}

なので、どうしても typeof  ・・ とか書きたくないなら、必ず存在する親要素を指定する。
#mycode{{
if (window.var1){
  alert("var1は定義済み。");
} else {
  alert("var1はundefined、null、false、0 のどれか");
}
}}

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

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

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

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


** クロージャ [#ke4c595d]
#mycode(){{
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);
}}

** プロトタイプチェーンによる継承 [#g45fd0b1]

#mycode(){{
// コンストラクタの定義
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]);
}
}}

実行結果
#myterm(){{
----- 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 + ")");
}
}}


トップ   一覧 単語検索 最終更新   ヘルプ   最終更新のRSS