[[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 + ")");
}
}}